Return to start page
Blizzard.j
1 //===========================================================================
2 // Blizzard.j ( define Jass2 functions that need to be in every map script )
3 //===========================================================================
4
5
6 globals
7 //-----------------------------------------------------------------------
8 // Constants
9 //
10
11 // Misc constants
12 constant real bj_PI = 3.14159
13 constant real bj_E = 2.71828
14 constant real bj_CELLWIDTH = 128.0
15 constant real bj_CLIFFHEIGHT = 128.0
16 constant real bj_UNIT_FACING = 270.0
17 constant real bj_RADTODEG = 180.0/bj_PI
18 constant real bj_DEGTORAD = bj_PI/180.0
19 constant real bj_TEXT_DELAY_QUEST = 20.00
20 constant real bj_TEXT_DELAY_QUESTUPDATE = 20.00
21 constant real bj_TEXT_DELAY_QUESTDONE = 20.00
22 constant real bj_TEXT_DELAY_QUESTFAILED = 20.00
23 constant real bj_TEXT_DELAY_QUESTREQUIREMENT = 20.00
24 constant real bj_TEXT_DELAY_MISSIONFAILED = 20.00
25 constant real bj_TEXT_DELAY_ALWAYSHINT = 12.00
26 constant real bj_TEXT_DELAY_HINT = 12.00
27 constant real bj_TEXT_DELAY_SECRET = 10.00
28 constant real bj_TEXT_DELAY_UNITACQUIRED = 15.00
29 constant real bj_TEXT_DELAY_UNITAVAILABLE = 10.00
30 constant real bj_TEXT_DELAY_ITEMACQUIRED = 10.00
31 constant real bj_TEXT_DELAY_WARNING = 12.00
32 constant real bj_QUEUE_DELAY_QUEST = 5.00
33 constant real bj_QUEUE_DELAY_HINT = 5.00
34 constant real bj_QUEUE_DELAY_SECRET = 3.00
35 constant real bj_HANDICAP_EASY = 60.00
36 constant real bj_GAME_STARTED_THRESHOLD = 0.01
37 constant real bj_WAIT_FOR_COND_MIN_INTERVAL = 0.10
38 constant real bj_POLLED_WAIT_INTERVAL = 0.10
39 constant real bj_POLLED_WAIT_SKIP_THRESHOLD = 2.00
40
41 // Game constants
42 constant integer bj_MAX_INVENTORY = 6
43 constant integer bj_MAX_PLAYERS = 12
44 constant integer bj_PLAYER_NEUTRAL_VICTIM = 13
45 constant integer bj_PLAYER_NEUTRAL_EXTRA = 14
46 constant integer bj_MAX_PLAYER_SLOTS = 16
47 constant integer bj_MAX_SKELETONS = 25
48 constant integer bj_MAX_STOCK_ITEM_SLOTS = 11
49 constant integer bj_MAX_STOCK_UNIT_SLOTS = 11
50 constant integer bj_MAX_ITEM_LEVEL = 10
51
52 // Ideally these would be looked up from Units/MiscData.txt,
53 // but there is currently no script functionality exposed to do that
54 constant real bj_TOD_DAWN = 6.00
55 constant real bj_TOD_DUSK = 18.00
56
57 // Melee game settings:
58 // - Starting Time of Day (TOD)
59 // - Starting Gold
60 // - Starting Lumber
61 // - Starting Hero Tokens (free heroes)
62 // - Max heroes allowed per player
63 // - Max heroes allowed per hero type
64 // - Distance from start loc to search for nearby mines
65 //
66 constant real bj_MELEE_STARTING_TOD = 8.00
67 constant integer bj_MELEE_STARTING_GOLD_V0 = 750
68 constant integer bj_MELEE_STARTING_GOLD_V1 = 500
69 constant integer bj_MELEE_STARTING_LUMBER_V0 = 200
70 constant integer bj_MELEE_STARTING_LUMBER_V1 = 150
71 constant integer bj_MELEE_STARTING_HERO_TOKENS = 1
72 constant integer bj_MELEE_HERO_LIMIT = 3
73 constant integer bj_MELEE_HERO_TYPE_LIMIT = 1
74 constant real bj_MELEE_MINE_SEARCH_RADIUS = 2000
75 constant real bj_MELEE_CLEAR_UNITS_RADIUS = 1500
76 constant real bj_MELEE_CRIPPLE_TIMEOUT = 120.00
77 constant real bj_MELEE_CRIPPLE_MSG_DURATION = 20.00
78 constant integer bj_MELEE_MAX_TWINKED_HEROES_V0 = 3
79 constant integer bj_MELEE_MAX_TWINKED_HEROES_V1 = 1
80
81 // Delay between a creep's death and the time it may drop an item.
82 constant real bj_CREEP_ITEM_DELAY = 0.50
83
84 // Timing settings for Marketplace inventories.
85 constant real bj_STOCK_RESTOCK_INITIAL_DELAY = 120
86 constant real bj_STOCK_RESTOCK_INTERVAL = 30
87 constant integer bj_STOCK_MAX_ITERATIONS = 20
88
89 // Max events registered by a single "dest dies in region" event.
90 constant integer bj_MAX_DEST_IN_REGION_EVENTS = 64
91
92 // Camera settings
93 constant integer bj_CAMERA_MIN_FARZ = 100
94 constant integer bj_CAMERA_DEFAULT_DISTANCE = 1650
95 constant integer bj_CAMERA_DEFAULT_FARZ = 5000
96 constant integer bj_CAMERA_DEFAULT_AOA = 304
97 constant integer bj_CAMERA_DEFAULT_FOV = 70
98 constant integer bj_CAMERA_DEFAULT_ROLL = 0
99 constant integer bj_CAMERA_DEFAULT_ROTATION = 90
100
101 // Rescue
102 constant real bj_RESCUE_PING_TIME = 2.00
103
104 // Transmission behavior settings
105 constant real bj_NOTHING_SOUND_DURATION = 5.00
106 constant real bj_TRANSMISSION_PING_TIME = 1.00
107 constant integer bj_TRANSMISSION_IND_RED = 255
108 constant integer bj_TRANSMISSION_IND_BLUE = 255
109 constant integer bj_TRANSMISSION_IND_GREEN = 255
110 constant integer bj_TRANSMISSION_IND_ALPHA = 255
111 constant real bj_TRANSMISSION_PORT_HANGTIME = 1.50
112
113 // Cinematic mode settings
114 constant real bj_CINEMODE_INTERFACEFADE = 0.50
115 constant gamespeed bj_CINEMODE_GAMESPEED = MAP_SPEED_NORMAL
116
117 // Cinematic mode volume levels
118 constant real bj_CINEMODE_VOLUME_UNITMOVEMENT = 0.40
119 constant real bj_CINEMODE_VOLUME_UNITSOUNDS = 0.00
120 constant real bj_CINEMODE_VOLUME_COMBAT = 0.40
121 constant real bj_CINEMODE_VOLUME_SPELLS = 0.40
122 constant real bj_CINEMODE_VOLUME_UI = 0.00
123 constant real bj_CINEMODE_VOLUME_MUSIC = 0.55
124 constant real bj_CINEMODE_VOLUME_AMBIENTSOUNDS = 1.00
125 constant real bj_CINEMODE_VOLUME_FIRE = 0.60
126
127 // Speech mode volume levels
128 constant real bj_SPEECH_VOLUME_UNITMOVEMENT = 0.25
129 constant real bj_SPEECH_VOLUME_UNITSOUNDS = 0.00
130 constant real bj_SPEECH_VOLUME_COMBAT = 0.25
131 constant real bj_SPEECH_VOLUME_SPELLS = 0.25
132 constant real bj_SPEECH_VOLUME_UI = 0.00
133 constant real bj_SPEECH_VOLUME_MUSIC = 0.55
134 constant real bj_SPEECH_VOLUME_AMBIENTSOUNDS = 1.00
135 constant real bj_SPEECH_VOLUME_FIRE = 0.60
136
137 // Smart pan settings
138 constant real bj_SMARTPAN_TRESHOLD_PAN = 500
139 constant real bj_SMARTPAN_TRESHOLD_SNAP = 3500
140
141 // QueuedTriggerExecute settings
142 constant integer bj_MAX_QUEUED_TRIGGERS = 100
143 constant real bj_QUEUED_TRIGGER_TIMEOUT = 180.00
144
145 // Campaign indexing constants
146 constant integer bj_CAMPAIGN_INDEX_T = 0
147 constant integer bj_CAMPAIGN_INDEX_H = 1
148 constant integer bj_CAMPAIGN_INDEX_U = 2
149 constant integer bj_CAMPAIGN_INDEX_O = 3
150 constant integer bj_CAMPAIGN_INDEX_N = 4
151 constant integer bj_CAMPAIGN_INDEX_XN = 5
152 constant integer bj_CAMPAIGN_INDEX_XH = 6
153 constant integer bj_CAMPAIGN_INDEX_XU = 7
154 constant integer bj_CAMPAIGN_INDEX_XO = 8
155
156 // Campaign offset constants (for mission indexing)
157 constant integer bj_CAMPAIGN_OFFSET_T = 0
158 constant integer bj_CAMPAIGN_OFFSET_H = 1
159 constant integer bj_CAMPAIGN_OFFSET_U = 2
160 constant integer bj_CAMPAIGN_OFFSET_O = 3
161 constant integer bj_CAMPAIGN_OFFSET_N = 4
162 constant integer bj_CAMPAIGN_OFFSET_XN = 0
163 constant integer bj_CAMPAIGN_OFFSET_XH = 1
164 constant integer bj_CAMPAIGN_OFFSET_XU = 2
165 constant integer bj_CAMPAIGN_OFFSET_XO = 3
166
167 // Mission indexing constants
168 // Tutorial
169 constant integer bj_MISSION_INDEX_T00 = bj_CAMPAIGN_OFFSET_T * 1000 + 0
170 constant integer bj_MISSION_INDEX_T01 = bj_CAMPAIGN_OFFSET_T * 1000 + 1
171 // Human
172 constant integer bj_MISSION_INDEX_H00 = bj_CAMPAIGN_OFFSET_H * 1000 + 0
173 constant integer bj_MISSION_INDEX_H01 = bj_CAMPAIGN_OFFSET_H * 1000 + 1
174 constant integer bj_MISSION_INDEX_H02 = bj_CAMPAIGN_OFFSET_H * 1000 + 2
175 constant integer bj_MISSION_INDEX_H03 = bj_CAMPAIGN_OFFSET_H * 1000 + 3
176 constant integer bj_MISSION_INDEX_H04 = bj_CAMPAIGN_OFFSET_H * 1000 + 4
177 constant integer bj_MISSION_INDEX_H05 = bj_CAMPAIGN_OFFSET_H * 1000 + 5
178 constant integer bj_MISSION_INDEX_H06 = bj_CAMPAIGN_OFFSET_H * 1000 + 6
179 constant integer bj_MISSION_INDEX_H07 = bj_CAMPAIGN_OFFSET_H * 1000 + 7
180 constant integer bj_MISSION_INDEX_H08 = bj_CAMPAIGN_OFFSET_H * 1000 + 8
181 constant integer bj_MISSION_INDEX_H09 = bj_CAMPAIGN_OFFSET_H * 1000 + 9
182 constant integer bj_MISSION_INDEX_H10 = bj_CAMPAIGN_OFFSET_H * 1000 + 10
183 constant integer bj_MISSION_INDEX_H11 = bj_CAMPAIGN_OFFSET_H * 1000 + 11
184 // Undead
185 constant integer bj_MISSION_INDEX_U00 = bj_CAMPAIGN_OFFSET_U * 1000 + 0
186 constant integer bj_MISSION_INDEX_U01 = bj_CAMPAIGN_OFFSET_U * 1000 + 1
187 constant integer bj_MISSION_INDEX_U02 = bj_CAMPAIGN_OFFSET_U * 1000 + 2
188 constant integer bj_MISSION_INDEX_U03 = bj_CAMPAIGN_OFFSET_U * 1000 + 3
189 constant integer bj_MISSION_INDEX_U05 = bj_CAMPAIGN_OFFSET_U * 1000 + 4
190 constant integer bj_MISSION_INDEX_U07 = bj_CAMPAIGN_OFFSET_U * 1000 + 5
191 constant integer bj_MISSION_INDEX_U08 = bj_CAMPAIGN_OFFSET_U * 1000 + 6
192 constant integer bj_MISSION_INDEX_U09 = bj_CAMPAIGN_OFFSET_U * 1000 + 7
193 constant integer bj_MISSION_INDEX_U10 = bj_CAMPAIGN_OFFSET_U * 1000 + 8
194 constant integer bj_MISSION_INDEX_U11 = bj_CAMPAIGN_OFFSET_U * 1000 + 9
195 // Orc
196 constant integer bj_MISSION_INDEX_O00 = bj_CAMPAIGN_OFFSET_O * 1000 + 0
197 constant integer bj_MISSION_INDEX_O01 = bj_CAMPAIGN_OFFSET_O * 1000 + 1
198 constant integer bj_MISSION_INDEX_O02 = bj_CAMPAIGN_OFFSET_O * 1000 + 2
199 constant integer bj_MISSION_INDEX_O03 = bj_CAMPAIGN_OFFSET_O * 1000 + 3
200 constant integer bj_MISSION_INDEX_O04 = bj_CAMPAIGN_OFFSET_O * 1000 + 4
201 constant integer bj_MISSION_INDEX_O05 = bj_CAMPAIGN_OFFSET_O * 1000 + 5
202 constant integer bj_MISSION_INDEX_O06 = bj_CAMPAIGN_OFFSET_O * 1000 + 6
203 constant integer bj_MISSION_INDEX_O07 = bj_CAMPAIGN_OFFSET_O * 1000 + 7
204 constant integer bj_MISSION_INDEX_O08 = bj_CAMPAIGN_OFFSET_O * 1000 + 8
205 constant integer bj_MISSION_INDEX_O09 = bj_CAMPAIGN_OFFSET_O * 1000 + 9
206 constant integer bj_MISSION_INDEX_O10 = bj_CAMPAIGN_OFFSET_O * 1000 + 10
207 // Night Elf
208 constant integer bj_MISSION_INDEX_N00 = bj_CAMPAIGN_OFFSET_N * 1000 + 0
209 constant integer bj_MISSION_INDEX_N01 = bj_CAMPAIGN_OFFSET_N * 1000 + 1
210 constant integer bj_MISSION_INDEX_N02 = bj_CAMPAIGN_OFFSET_N * 1000 + 2
211 constant integer bj_MISSION_INDEX_N03 = bj_CAMPAIGN_OFFSET_N * 1000 + 3
212 constant integer bj_MISSION_INDEX_N04 = bj_CAMPAIGN_OFFSET_N * 1000 + 4
213 constant integer bj_MISSION_INDEX_N05 = bj_CAMPAIGN_OFFSET_N * 1000 + 5
214 constant integer bj_MISSION_INDEX_N06 = bj_CAMPAIGN_OFFSET_N * 1000 + 6
215 constant integer bj_MISSION_INDEX_N07 = bj_CAMPAIGN_OFFSET_N * 1000 + 7
216 constant integer bj_MISSION_INDEX_N08 = bj_CAMPAIGN_OFFSET_N * 1000 + 8
217 constant integer bj_MISSION_INDEX_N09 = bj_CAMPAIGN_OFFSET_N * 1000 + 9
218 // Expansion Night Elf
219 constant integer bj_MISSION_INDEX_XN00 = bj_CAMPAIGN_OFFSET_XN * 1000 + 0
220 constant integer bj_MISSION_INDEX_XN01 = bj_CAMPAIGN_OFFSET_XN * 1000 + 1
221 constant integer bj_MISSION_INDEX_XN02 = bj_CAMPAIGN_OFFSET_XN * 1000 + 2
222 constant integer bj_MISSION_INDEX_XN03 = bj_CAMPAIGN_OFFSET_XN * 1000 + 3
223 constant integer bj_MISSION_INDEX_XN04 = bj_CAMPAIGN_OFFSET_XN * 1000 + 4
224 constant integer bj_MISSION_INDEX_XN05 = bj_CAMPAIGN_OFFSET_XN * 1000 + 5
225 constant integer bj_MISSION_INDEX_XN06 = bj_CAMPAIGN_OFFSET_XN * 1000 + 6
226 constant integer bj_MISSION_INDEX_XN07 = bj_CAMPAIGN_OFFSET_XN * 1000 + 7
227 constant integer bj_MISSION_INDEX_XN08 = bj_CAMPAIGN_OFFSET_XN * 1000 + 8
228 constant integer bj_MISSION_INDEX_XN09 = bj_CAMPAIGN_OFFSET_XN * 1000 + 9
229 constant integer bj_MISSION_INDEX_XN10 = bj_CAMPAIGN_OFFSET_XN * 1000 + 10
230 // Expansion Human
231 constant integer bj_MISSION_INDEX_XH00 = bj_CAMPAIGN_OFFSET_XH * 1000 + 0
232 constant integer bj_MISSION_INDEX_XH01 = bj_CAMPAIGN_OFFSET_XH * 1000 + 1
233 constant integer bj_MISSION_INDEX_XH02 = bj_CAMPAIGN_OFFSET_XH * 1000 + 2
234 constant integer bj_MISSION_INDEX_XH03 = bj_CAMPAIGN_OFFSET_XH * 1000 + 3
235 constant integer bj_MISSION_INDEX_XH04 = bj_CAMPAIGN_OFFSET_XH * 1000 + 4
236 constant integer bj_MISSION_INDEX_XH05 = bj_CAMPAIGN_OFFSET_XH * 1000 + 5
237 constant integer bj_MISSION_INDEX_XH06 = bj_CAMPAIGN_OFFSET_XH * 1000 + 6
238 constant integer bj_MISSION_INDEX_XH07 = bj_CAMPAIGN_OFFSET_XH * 1000 + 7
239 constant integer bj_MISSION_INDEX_XH08 = bj_CAMPAIGN_OFFSET_XH * 1000 + 8
240 constant integer bj_MISSION_INDEX_XH09 = bj_CAMPAIGN_OFFSET_XH * 1000 + 9
241 // Expansion Undead
242 constant integer bj_MISSION_INDEX_XU00 = bj_CAMPAIGN_OFFSET_XU * 1000 + 0
243 constant integer bj_MISSION_INDEX_XU01 = bj_CAMPAIGN_OFFSET_XU * 1000 + 1
244 constant integer bj_MISSION_INDEX_XU02 = bj_CAMPAIGN_OFFSET_XU * 1000 + 2
245 constant integer bj_MISSION_INDEX_XU03 = bj_CAMPAIGN_OFFSET_XU * 1000 + 3
246 constant integer bj_MISSION_INDEX_XU04 = bj_CAMPAIGN_OFFSET_XU * 1000 + 4
247 constant integer bj_MISSION_INDEX_XU05 = bj_CAMPAIGN_OFFSET_XU * 1000 + 5
248 constant integer bj_MISSION_INDEX_XU06 = bj_CAMPAIGN_OFFSET_XU * 1000 + 6
249 constant integer bj_MISSION_INDEX_XU07 = bj_CAMPAIGN_OFFSET_XU * 1000 + 7
250 constant integer bj_MISSION_INDEX_XU08 = bj_CAMPAIGN_OFFSET_XU * 1000 + 8
251 constant integer bj_MISSION_INDEX_XU09 = bj_CAMPAIGN_OFFSET_XU * 1000 + 9
252 constant integer bj_MISSION_INDEX_XU10 = bj_CAMPAIGN_OFFSET_XU * 1000 + 10
253 constant integer bj_MISSION_INDEX_XU11 = bj_CAMPAIGN_OFFSET_XU * 1000 + 11
254 constant integer bj_MISSION_INDEX_XU12 = bj_CAMPAIGN_OFFSET_XU * 1000 + 12
255 constant integer bj_MISSION_INDEX_XU13 = bj_CAMPAIGN_OFFSET_XU * 1000 + 13
256
257 // Expansion Orc
258 constant integer bj_MISSION_INDEX_XO00 = bj_CAMPAIGN_OFFSET_XO * 1000 + 0
259
260 // Cinematic indexing constants
261 constant integer bj_CINEMATICINDEX_TOP = 0
262 constant integer bj_CINEMATICINDEX_HOP = 1
263 constant integer bj_CINEMATICINDEX_HED = 2
264 constant integer bj_CINEMATICINDEX_OOP = 3
265 constant integer bj_CINEMATICINDEX_OED = 4
266 constant integer bj_CINEMATICINDEX_UOP = 5
267 constant integer bj_CINEMATICINDEX_UED = 6
268 constant integer bj_CINEMATICINDEX_NOP = 7
269 constant integer bj_CINEMATICINDEX_NED = 8
270 constant integer bj_CINEMATICINDEX_XOP = 9
271 constant integer bj_CINEMATICINDEX_XED = 10
272
273 // Alliance settings
274 constant integer bj_ALLIANCE_UNALLIED = 0
275 constant integer bj_ALLIANCE_UNALLIED_VISION = 1
276 constant integer bj_ALLIANCE_ALLIED = 2
277 constant integer bj_ALLIANCE_ALLIED_VISION = 3
278 constant integer bj_ALLIANCE_ALLIED_UNITS = 4
279 constant integer bj_ALLIANCE_ALLIED_ADVUNITS = 5
280 constant integer bj_ALLIANCE_NEUTRAL = 6
281 constant integer bj_ALLIANCE_NEUTRAL_VISION = 7
282
283 // Keyboard Event Types
284 constant integer bj_KEYEVENTTYPE_DEPRESS = 0
285 constant integer bj_KEYEVENTTYPE_RELEASE = 1
286
287 // Keyboard Event Keys
288 constant integer bj_KEYEVENTKEY_LEFT = 0
289 constant integer bj_KEYEVENTKEY_RIGHT = 1
290 constant integer bj_KEYEVENTKEY_DOWN = 2
291 constant integer bj_KEYEVENTKEY_UP = 3
292
293 // Transmission timing methods
294 constant integer bj_TIMETYPE_ADD = 0
295 constant integer bj_TIMETYPE_SET = 1
296 constant integer bj_TIMETYPE_SUB = 2
297
298 // Camera bounds adjustment methods
299 constant integer bj_CAMERABOUNDS_ADJUST_ADD = 0
300 constant integer bj_CAMERABOUNDS_ADJUST_SUB = 1
301
302 // Quest creation states
303 constant integer bj_QUESTTYPE_REQ_DISCOVERED = 0
304 constant integer bj_QUESTTYPE_REQ_UNDISCOVERED = 1
305 constant integer bj_QUESTTYPE_OPT_DISCOVERED = 2
306 constant integer bj_QUESTTYPE_OPT_UNDISCOVERED = 3
307
308 // Quest message types
309 constant integer bj_QUESTMESSAGE_DISCOVERED = 0
310 constant integer bj_QUESTMESSAGE_UPDATED = 1
311 constant integer bj_QUESTMESSAGE_COMPLETED = 2
312 constant integer bj_QUESTMESSAGE_FAILED = 3
313 constant integer bj_QUESTMESSAGE_REQUIREMENT = 4
314 constant integer bj_QUESTMESSAGE_MISSIONFAILED = 5
315 constant integer bj_QUESTMESSAGE_ALWAYSHINT = 6
316 constant integer bj_QUESTMESSAGE_HINT = 7
317 constant integer bj_QUESTMESSAGE_SECRET = 8
318 constant integer bj_QUESTMESSAGE_UNITACQUIRED = 9
319 constant integer bj_QUESTMESSAGE_UNITAVAILABLE = 10
320 constant integer bj_QUESTMESSAGE_ITEMACQUIRED = 11
321 constant integer bj_QUESTMESSAGE_WARNING = 12
322
323 // Leaderboard sorting methods
324 constant integer bj_SORTTYPE_SORTBYVALUE = 0
325 constant integer bj_SORTTYPE_SORTBYPLAYER = 1
326 constant integer bj_SORTTYPE_SORTBYLABEL = 2
327
328 // Cinematic fade filter methods
329 constant integer bj_CINEFADETYPE_FADEIN = 0
330 constant integer bj_CINEFADETYPE_FADEOUT = 1
331 constant integer bj_CINEFADETYPE_FADEOUTIN = 2
332
333 // Buff removal methods
334 constant integer bj_REMOVEBUFFS_POSITIVE = 0
335 constant integer bj_REMOVEBUFFS_NEGATIVE = 1
336 constant integer bj_REMOVEBUFFS_ALL = 2
337 constant integer bj_REMOVEBUFFS_NONTLIFE = 3
338
339 // Buff properties - polarity
340 constant integer bj_BUFF_POLARITY_POSITIVE = 0
341 constant integer bj_BUFF_POLARITY_NEGATIVE = 1
342 constant integer bj_BUFF_POLARITY_EITHER = 2
343
344 // Buff properties - resist type
345 constant integer bj_BUFF_RESIST_MAGIC = 0
346 constant integer bj_BUFF_RESIST_PHYSICAL = 1
347 constant integer bj_BUFF_RESIST_EITHER = 2
348 constant integer bj_BUFF_RESIST_BOTH = 3
349
350 // Hero stats
351 constant integer bj_HEROSTAT_STR = 0
352 constant integer bj_HEROSTAT_AGI = 1
353 constant integer bj_HEROSTAT_INT = 2
354
355 // Hero skill point modification methods
356 constant integer bj_MODIFYMETHOD_ADD = 0
357 constant integer bj_MODIFYMETHOD_SUB = 1
358 constant integer bj_MODIFYMETHOD_SET = 2
359
360 // Unit state adjustment methods (for replaced units)
361 constant integer bj_UNIT_STATE_METHOD_ABSOLUTE = 0
362 constant integer bj_UNIT_STATE_METHOD_RELATIVE = 1
363 constant integer bj_UNIT_STATE_METHOD_DEFAULTS = 2
364 constant integer bj_UNIT_STATE_METHOD_MAXIMUM = 3
365
366 // Gate operations
367 constant integer bj_GATEOPERATION_CLOSE = 0
368 constant integer bj_GATEOPERATION_OPEN = 1
369 constant integer bj_GATEOPERATION_DESTROY = 2
370
371 // Game cache value types
372 constant integer bj_GAMECACHE_BOOLEAN = 0
373 constant integer bj_GAMECACHE_INTEGER = 1
374 constant integer bj_GAMECACHE_REAL = 2
375 constant integer bj_GAMECACHE_UNIT = 3
376 constant integer bj_GAMECACHE_STRING = 4
377
378 // Item status types
379 constant integer bj_ITEM_STATUS_HIDDEN = 0
380 constant integer bj_ITEM_STATUS_OWNED = 1
381 constant integer bj_ITEM_STATUS_INVULNERABLE = 2
382 constant integer bj_ITEM_STATUS_POWERUP = 3
383 constant integer bj_ITEM_STATUS_SELLABLE = 4
384 constant integer bj_ITEM_STATUS_PAWNABLE = 5
385
386 // Itemcode status types
387 constant integer bj_ITEMCODE_STATUS_POWERUP = 0
388 constant integer bj_ITEMCODE_STATUS_SELLABLE = 1
389 constant integer bj_ITEMCODE_STATUS_PAWNABLE = 2
390
391 // Minimap ping styles
392 constant integer bj_MINIMAPPINGSTYLE_SIMPLE = 0
393 constant integer bj_MINIMAPPINGSTYLE_FLASHY = 1
394 constant integer bj_MINIMAPPINGSTYLE_ATTACK = 2
395
396 // Corpse creation settings
397 constant real bj_CORPSE_MAX_DEATH_TIME = 8.00
398
399 // Corpse creation styles
400 constant integer bj_CORPSETYPE_FLESH = 0
401 constant integer bj_CORPSETYPE_BONE = 1
402
403 // Elevator pathing-blocker destructable code
404 constant integer bj_ELEVATOR_BLOCKER_CODE = 'DTep'
405 constant integer bj_ELEVATOR_CODE01 = 'DTrf'
406 constant integer bj_ELEVATOR_CODE02 = 'DTrx'
407
408 // Elevator wall codes
409 constant integer bj_ELEVATOR_WALL_TYPE_ALL = 0
410 constant integer bj_ELEVATOR_WALL_TYPE_EAST = 1
411 constant integer bj_ELEVATOR_WALL_TYPE_NORTH = 2
412 constant integer bj_ELEVATOR_WALL_TYPE_SOUTH = 3
413 constant integer bj_ELEVATOR_WALL_TYPE_WEST = 4
414
415 //-----------------------------------------------------------------------
416 // Variables
417 //
418
419 // Force predefs
420 force bj_FORCE_ALL_PLAYERS = null
421 force array bj_FORCE_PLAYER
422
423 integer bj_MELEE_MAX_TWINKED_HEROES = 0
424
425 // Map area rects
426 rect bj_mapInitialPlayableArea = null
427 rect bj_mapInitialCameraBounds = null
428
429 // Utility function vars
430 integer bj_forLoopAIndex = 0
431 integer bj_forLoopBIndex = 0
432 integer bj_forLoopAIndexEnd = 0
433 integer bj_forLoopBIndexEnd = 0
434
435 boolean bj_slotControlReady = false
436 boolean array bj_slotControlUsed
437 mapcontrol array bj_slotControl
438
439 // Game started detection vars
440 timer bj_gameStartedTimer = null
441 boolean bj_gameStarted = false
442 timer bj_volumeGroupsTimer = CreateTimer()
443
444 // Singleplayer check
445 boolean bj_isSinglePlayer = false
446
447 // Day/Night Cycle vars
448 trigger bj_dncSoundsDay = null
449 trigger bj_dncSoundsNight = null
450 sound bj_dayAmbientSound = null
451 sound bj_nightAmbientSound = null
452 trigger bj_dncSoundsDawn = null
453 trigger bj_dncSoundsDusk = null
454 sound bj_dawnSound = null
455 sound bj_duskSound = null
456 boolean bj_useDawnDuskSounds = true
457 boolean bj_dncIsDaytime = false
458
459 // Triggered sounds
460 //sound bj_pingMinimapSound = null
461 sound bj_rescueSound = null
462 sound bj_questDiscoveredSound = null
463 sound bj_questUpdatedSound = null
464 sound bj_questCompletedSound = null
465 sound bj_questFailedSound = null
466 sound bj_questHintSound = null
467 sound bj_questSecretSound = null
468 sound bj_questItemAcquiredSound = null
469 sound bj_questWarningSound = null
470 sound bj_victoryDialogSound = null
471 sound bj_defeatDialogSound = null
472
473 // Marketplace vars
474 trigger bj_stockItemPurchased = null
475 timer bj_stockUpdateTimer = null
476 boolean array bj_stockAllowedPermanent
477 boolean array bj_stockAllowedCharged
478 boolean array bj_stockAllowedArtifact
479 integer bj_stockPickedItemLevel = 0
480 itemtype bj_stockPickedItemType
481
482 // Melee vars
483 trigger bj_meleeVisibilityTrained = null
484 boolean bj_meleeVisibilityIsDay = true
485 boolean bj_meleeGrantHeroItems = false
486 location bj_meleeNearestMineToLoc = null
487 unit bj_meleeNearestMine = null
488 real bj_meleeNearestMineDist = 0.00
489 boolean bj_meleeGameOver = false
490 boolean array bj_meleeDefeated
491 boolean array bj_meleeVictoried
492 unit array bj_ghoul
493 timer array bj_crippledTimer
494 timerdialog array bj_crippledTimerWindows
495 boolean array bj_playerIsCrippled
496 boolean array bj_playerIsExposed
497 boolean bj_finishSoonAllExposed = false
498 timerdialog bj_finishSoonTimerDialog = null
499 integer array bj_meleeTwinkedHeroes
500
501 // Rescue behavior vars
502 trigger bj_rescueUnitBehavior = null
503 boolean bj_rescueChangeColorUnit = true
504 boolean bj_rescueChangeColorBldg = true
505
506 // Transmission vars
507 timer bj_cineSceneEndingTimer = null
508 sound bj_cineSceneLastSound = null
509 trigger bj_cineSceneBeingSkipped = null
510
511 // Cinematic mode vars
512 gamespeed bj_cineModePriorSpeed = MAP_SPEED_NORMAL
513 boolean bj_cineModePriorFogSetting = false
514 boolean bj_cineModePriorMaskSetting = false
515 boolean bj_cineModeAlreadyIn = false
516 boolean bj_cineModePriorDawnDusk = false
517 integer bj_cineModeSavedSeed = 0
518
519 // Cinematic fade vars
520 timer bj_cineFadeFinishTimer = null
521 timer bj_cineFadeContinueTimer = null
522 real bj_cineFadeContinueRed = 0
523 real bj_cineFadeContinueGreen = 0
524 real bj_cineFadeContinueBlue = 0
525 real bj_cineFadeContinueTrans = 0
526 real bj_cineFadeContinueDuration = 0
527 string bj_cineFadeContinueTex = ""
528
529 // QueuedTriggerExecute vars
530 integer bj_queuedExecTotal = 0
531 trigger array bj_queuedExecTriggers
532 boolean array bj_queuedExecUseConds
533 timer bj_queuedExecTimeoutTimer = CreateTimer()
534 trigger bj_queuedExecTimeout = null
535
536 // Helper vars (for Filter and Enum funcs)
537 integer bj_destInRegionDiesCount = 0
538 trigger bj_destInRegionDiesTrig = null
539 integer bj_groupCountUnits = 0
540 integer bj_forceCountPlayers = 0
541 integer bj_groupEnumTypeId = 0
542 player bj_groupEnumOwningPlayer = null
543 group bj_groupAddGroupDest = null
544 group bj_groupRemoveGroupDest = null
545 integer bj_groupRandomConsidered = 0
546 unit bj_groupRandomCurrentPick = null
547 group bj_groupLastCreatedDest = null
548 group bj_randomSubGroupGroup = null
549 integer bj_randomSubGroupWant = 0
550 integer bj_randomSubGroupTotal = 0
551 real bj_randomSubGroupChance = 0
552 integer bj_destRandomConsidered = 0
553 destructable bj_destRandomCurrentPick = null
554 destructable bj_elevatorWallBlocker = null
555 destructable bj_elevatorNeighbor = null
556 integer bj_itemRandomConsidered = 0
557 item bj_itemRandomCurrentPick = null
558 integer bj_forceRandomConsidered = 0
559 player bj_forceRandomCurrentPick = null
560 unit bj_makeUnitRescuableUnit = null
561 boolean bj_makeUnitRescuableFlag = true
562 boolean bj_pauseAllUnitsFlag = true
563 location bj_enumDestructableCenter = null
564 real bj_enumDestructableRadius = 0
565 playercolor bj_setPlayerTargetColor = null
566 boolean bj_isUnitGroupDeadResult = true
567 boolean bj_isUnitGroupEmptyResult = true
568 boolean bj_isUnitGroupInRectResult = true
569 rect bj_isUnitGroupInRectRect = null
570 boolean bj_changeLevelShowScores = false
571 string bj_changeLevelMapName = null
572 group bj_suspendDecayFleshGroup = CreateGroup()
573 group bj_suspendDecayBoneGroup = CreateGroup()
574 timer bj_delayedSuspendDecayTimer = CreateTimer()
575 trigger bj_delayedSuspendDecayTrig = null
576 integer bj_livingPlayerUnitsTypeId = 0
577 widget bj_lastDyingWidget = null
578
579 // Random distribution vars
580 integer bj_randDistCount = 0
581 integer array bj_randDistID
582 integer array bj_randDistChance
583
584 // Last X'd vars
585 unit bj_lastCreatedUnit = null
586 item bj_lastCreatedItem = null
587 item bj_lastRemovedItem = null
588 unit bj_lastHauntedGoldMine = null
589 destructable bj_lastCreatedDestructable = null
590 group bj_lastCreatedGroup = CreateGroup()
591 fogmodifier bj_lastCreatedFogModifier = null
592 effect bj_lastCreatedEffect = null
593 weathereffect bj_lastCreatedWeatherEffect = null
594 terraindeformation bj_lastCreatedTerrainDeformation = null
595 quest bj_lastCreatedQuest = null
596 questitem bj_lastCreatedQuestItem = null
597 defeatcondition bj_lastCreatedDefeatCondition = null
598 timer bj_lastStartedTimer = CreateTimer()
599 timerdialog bj_lastCreatedTimerDialog = null
600 leaderboard bj_lastCreatedLeaderboard = null
601 multiboard bj_lastCreatedMultiboard = null
602 sound bj_lastPlayedSound = null
603 string bj_lastPlayedMusic = ""
604 real bj_lastTransmissionDuration = 0
605 gamecache bj_lastCreatedGameCache = null
606 unit bj_lastLoadedUnit = null
607 button bj_lastCreatedButton = null
608 unit bj_lastReplacedUnit = null
609 texttag bj_lastCreatedTextTag = null
610 lightning bj_lastCreatedLightning = null
611 image bj_lastCreatedImage = null
612 ubersplat bj_lastCreatedUbersplat = null
613
614 // Filter function vars
615 boolexpr filterIssueHauntOrderAtLocBJ = null
616 boolexpr filterEnumDestructablesInCircleBJ = null
617 boolexpr filterGetUnitsInRectOfPlayer = null
618 boolexpr filterGetUnitsOfTypeIdAll = null
619 boolexpr filterGetUnitsOfPlayerAndTypeId = null
620 boolexpr filterMeleeTrainedUnitIsHeroBJ = null
621 boolexpr filterLivingPlayerUnitsOfTypeId = null
622
623 // Memory cleanup vars
624 boolean bj_wantDestroyGroup = false
625 endglobals
626
627
628
629 //***************************************************************************
630 //*
631 //* Debugging Functions
632 //*
633 //***************************************************************************
634
635 //===========================================================================
636 function BJDebugMsg takes string msg returns nothing
637 local integer i = 0
638 loop
639 call DisplayTimedTextToPlayer(Player(i),0,0,60,msg)
640 set i = i + 1
641 exitwhen i == bj_MAX_PLAYERS
642 endloop
643 endfunction
644
645
646
647 //***************************************************************************
648 //*
649 //* Math Utility Functions
650 //*
651 //***************************************************************************
652
653 //===========================================================================
654 function RMinBJ takes real a, real b returns real
655 if (a < b) then
656 return a
657 else
658 return b
659 endif
660 endfunction
661
662 //===========================================================================
663 function RMaxBJ takes real a, real b returns real
664 if (a < b) then
665 return b
666 else
667 return a
668 endif
669 endfunction
670
671 //===========================================================================
672 function RAbsBJ takes real a returns real
673 if (a >= 0) then
674 return a
675 else
676 return -a
677 endif
678 endfunction
679
680 //===========================================================================
681 function RSignBJ takes real a returns real
682 if (a >= 0.0) then
683 return 1.0
684 else
685 return -1.0
686 endif
687 endfunction
688
689 //===========================================================================
690 function IMinBJ takes integer a, integer b returns integer
691 if (a < b) then
692 return a
693 else
694 return b
695 endif
696 endfunction
697
698 //===========================================================================
699 function IMaxBJ takes integer a, integer b returns integer
700 if (a < b) then
701 return b
702 else
703 return a
704 endif
705 endfunction
706
707 //===========================================================================
708 function IAbsBJ takes integer a returns integer
709 if (a >= 0) then
710 return a
711 else
712 return -a
713 endif
714 endfunction
715
716 //===========================================================================
717 function ISignBJ takes integer a returns integer
718 if (a >= 0) then
719 return 1
720 else
721 return -1
722 endif
723 endfunction
724
725 //===========================================================================
726 function SinBJ takes real degrees returns real
727 return Sin(degrees * bj_DEGTORAD)
728 endfunction
729
730 //===========================================================================
731 function CosBJ takes real degrees returns real
732 return Cos(degrees * bj_DEGTORAD)
733 endfunction
734
735 //===========================================================================
736 function TanBJ takes real degrees returns real
737 return Tan(degrees * bj_DEGTORAD)
738 endfunction
739
740 //===========================================================================
741 function AsinBJ takes real degrees returns real
742 return Asin(degrees) * bj_RADTODEG
743 endfunction
744
745 //===========================================================================
746 function AcosBJ takes real degrees returns real
747 return Acos(degrees) * bj_RADTODEG
748 endfunction
749
750 //===========================================================================
751 function AtanBJ takes real degrees returns real
752 return Atan(degrees) * bj_RADTODEG
753 endfunction
754
755 //===========================================================================
756 function Atan2BJ takes real y, real x returns real
757 return Atan2(y, x) * bj_RADTODEG
758 endfunction
759
760 //===========================================================================
761 function AngleBetweenPoints takes location locA, location locB returns real
762 return bj_RADTODEG * Atan2(GetLocationY(locB) - GetLocationY(locA), GetLocationX(locB) - GetLocationX(locA))
763 endfunction
764
765 //===========================================================================
766 function DistanceBetweenPoints takes location locA, location locB returns real
767 local real dx = GetLocationX(locB) - GetLocationX(locA)
768 local real dy = GetLocationY(locB) - GetLocationY(locA)
769 return SquareRoot(dx * dx + dy * dy)
770 endfunction
771
772 //===========================================================================
773 function PolarProjectionBJ takes location source, real dist, real angle returns location
774 local real x = GetLocationX(source) + dist * Cos(angle * bj_DEGTORAD)
775 local real y = GetLocationY(source) + dist * Sin(angle * bj_DEGTORAD)
776 return Location(x, y)
777 endfunction
778
779 //===========================================================================
780 function GetRandomDirectionDeg takes nothing returns real
781 return GetRandomReal(0, 360)
782 endfunction
783
784 //===========================================================================
785 function GetRandomPercentageBJ takes nothing returns real
786 return GetRandomReal(0, 100)
787 endfunction
788
789 //===========================================================================
790 function GetRandomLocInRect takes rect whichRect returns location
791 return Location(GetRandomReal(GetRectMinX(whichRect), GetRectMaxX(whichRect)), GetRandomReal(GetRectMinY(whichRect), GetRectMaxY(whichRect)))
792 endfunction
793
794 //===========================================================================
795 // Calculate the modulus/remainder of (dividend) divided by (divisor).
796 // Examples: 18 mod 5 = 3. 15 mod 5 = 0. -8 mod 5 = 2.
797 //
798 function ModuloInteger takes integer dividend, integer divisor returns integer
799 local integer modulus = dividend - (dividend / divisor) * divisor
800
801 // If the dividend was negative, the above modulus calculation will
802 // be negative, but within (-divisor..0). We can add (divisor) to
803 // shift this result into the desired range of (0..divisor).
804 if (modulus < 0) then
805 set modulus = modulus + divisor
806 endif
807
808 return modulus
809 endfunction
810
811 //===========================================================================
812 // Calculate the modulus/remainder of (dividend) divided by (divisor).
813 // Examples: 13.000 mod 2.500 = 0.500. -6.000 mod 2.500 = 1.500.
814 //
815 function ModuloReal takes real dividend, real divisor returns real
816 local real modulus = dividend - I2R(R2I(dividend / divisor)) * divisor
817
818 // If the dividend was negative, the above modulus calculation will
819 // be negative, but within (-divisor..0). We can add (divisor) to
820 // shift this result into the desired range of (0..divisor).
821 if (modulus < 0) then
822 set modulus = modulus + divisor
823 endif
824
825 return modulus
826 endfunction
827
828 //===========================================================================
829 function OffsetLocation takes location loc, real dx, real dy returns location
830 return Location(GetLocationX(loc) + dx, GetLocationY(loc) + dy)
831 endfunction
832
833 //===========================================================================
834 function OffsetRectBJ takes rect r, real dx, real dy returns rect
835 return Rect( GetRectMinX(r) + dx, GetRectMinY(r) + dy, GetRectMaxX(r) + dx, GetRectMaxY(r) + dy )
836 endfunction
837
838 //===========================================================================
839 function RectFromCenterSizeBJ takes location center, real width, real height returns rect
840 local real x = GetLocationX( center )
841 local real y = GetLocationY( center )
842 return Rect( x - width*0.5, y - height*0.5, x + width*0.5, y + height*0.5 )
843 endfunction
844
845 //===========================================================================
846 function RectContainsCoords takes rect r, real x, real y returns boolean
847 return (GetRectMinX(r) <= x) and (x <= GetRectMaxX(r)) and (GetRectMinY(r) <= y) and (y <= GetRectMaxY(r))
848 endfunction
849
850 //===========================================================================
851 function RectContainsLoc takes rect r, location loc returns boolean
852 return RectContainsCoords(r, GetLocationX(loc), GetLocationY(loc))
853 endfunction
854
855 //===========================================================================
856 function RectContainsUnit takes rect r, unit whichUnit returns boolean
857 return RectContainsCoords(r, GetUnitX(whichUnit), GetUnitY(whichUnit))
858 endfunction
859
860 //===========================================================================
861 function RectContainsItem takes item whichItem, rect r returns boolean
862 if (whichItem == null) then
863 return false
864 endif
865
866 if (IsItemOwned(whichItem)) then
867 return false
868 endif
869
870 return RectContainsCoords(r, GetItemX(whichItem), GetItemY(whichItem))
871 endfunction
872
873
874
875 //***************************************************************************
876 //*
877 //* Utility Constructs
878 //*
879 //***************************************************************************
880
881 //===========================================================================
882 // Runs the trigger's actions if the trigger's conditions evaluate to true.
883 //
884 function ConditionalTriggerExecute takes trigger trig returns nothing
885 if TriggerEvaluate(trig) then
886 call TriggerExecute(trig)
887 endif
888 endfunction
889
890 //===========================================================================
891 // Runs the trigger's actions if the trigger's conditions evaluate to true.
892 //
893 function TriggerExecuteBJ takes trigger trig, boolean checkConditions returns boolean
894 if checkConditions then
895 if not (TriggerEvaluate(trig)) then
896 return false
897 endif
898 endif
899 call TriggerExecute(trig)
900 return true
901 endfunction
902
903 //===========================================================================
904 // Arranges for a trigger to fire almost immediately, except that the calling
905 // trigger is not interrupted as is the case with a TriggerExecute call.
906 // Since the trigger executes normally, its conditions are still evaluated.
907 //
908 function PostTriggerExecuteBJ takes trigger trig, boolean checkConditions returns boolean
909 if checkConditions then
910 if not (TriggerEvaluate(trig)) then
911 return false
912 endif
913 endif
914 call TriggerRegisterTimerEvent(trig, 0, false)
915 return true
916 endfunction
917
918 //===========================================================================
919 // Debug - Display the contents of the trigger queue (as either null or "x"
920 // for each entry).
921 function QueuedTriggerCheck takes nothing returns nothing
922 local string s = "TrigQueue Check "
923 local integer i
924
925 set i = 0
926 loop
927 exitwhen i >= bj_queuedExecTotal
928 set s = s + "q[" + I2S(i) + "]="
929 if (bj_queuedExecTriggers[i] == null) then
930 set s = s + "null "
931 else
932 set s = s + "x "
933 endif
934 set i = i + 1
935 endloop
936 set s = s + "(" + I2S(bj_queuedExecTotal) + " total)"
937 call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,600,s)
938 endfunction
939
940 //===========================================================================
941 // Searches the queue for a given trigger, returning the index of the
942 // trigger within the queue if it is found, or -1 if it is not found.
943 //
944 function QueuedTriggerGetIndex takes trigger trig returns integer
945 // Determine which, if any, of the queued triggers is being removed.
946 local integer index = 0
947 loop
948 exitwhen index >= bj_queuedExecTotal
949 if (bj_queuedExecTriggers[index] == trig) then
950 return index
951 endif
952 set index = index + 1
953 endloop
954 return -1
955 endfunction
956
957 //===========================================================================
958 // Removes a trigger from the trigger queue, shifting other triggers down
959 // to fill the unused space. If the currently running trigger is removed
960 // in this manner, this function does NOT attempt to run the next trigger.
961 //
962 function QueuedTriggerRemoveByIndex takes integer trigIndex returns boolean
963 local integer index
964
965 // If the to-be-removed index is out of range, fail.
966 if (trigIndex >= bj_queuedExecTotal) then
967 return false
968 endif
969
970 // Shift all queue entries down to fill in the gap.
971 set bj_queuedExecTotal = bj_queuedExecTotal - 1
972 set index = trigIndex
973 loop
974 exitwhen index >= bj_queuedExecTotal
975 set bj_queuedExecTriggers[index] = bj_queuedExecTriggers[index + 1]
976 set bj_queuedExecUseConds[index] = bj_queuedExecUseConds[index + 1]
977 set index = index + 1
978 endloop
979 return true
980 endfunction
981
982 //===========================================================================
983 // Attempt to execute the first trigger in the queue. If it fails, remove
984 // it and execute the next one. Continue this cycle until a trigger runs,
985 // or until the queue is empty.
986 //
987 function QueuedTriggerAttemptExec takes nothing returns boolean
988 loop
989 exitwhen bj_queuedExecTotal == 0
990
991 if TriggerExecuteBJ(bj_queuedExecTriggers[0], bj_queuedExecUseConds[0]) then
992 // Timeout the queue if it sits at the front of the queue for too long.
993 call TimerStart(bj_queuedExecTimeoutTimer, bj_QUEUED_TRIGGER_TIMEOUT, false, null)
994 return true
995 endif
996
997 call QueuedTriggerRemoveByIndex(0)
998 endloop
999 return false
1000 endfunction
1001
1002 //===========================================================================
1003 // Queues a trigger to be executed, assuring that such triggers are not
1004 // executed at the same time.
1005 //
1006 function QueuedTriggerAddBJ takes trigger trig, boolean checkConditions returns boolean
1007 // Make sure our queue isn't full. If it is, return failure.
1008 if (bj_queuedExecTotal >= bj_MAX_QUEUED_TRIGGERS) then
1009 return false
1010 endif
1011
1012 // Add the trigger to an array of to-be-executed triggers.
1013 set bj_queuedExecTriggers[bj_queuedExecTotal] = trig
1014 set bj_queuedExecUseConds[bj_queuedExecTotal] = checkConditions
1015 set bj_queuedExecTotal = bj_queuedExecTotal + 1
1016
1017 // If this is the only trigger in the queue, run it.
1018 if (bj_queuedExecTotal == 1) then
1019 call QueuedTriggerAttemptExec()
1020 endif
1021 return true
1022 endfunction
1023
1024 //===========================================================================
1025 // Denotes the end of a queued trigger. Be sure to call this only once per
1026 // queued trigger, or risk stepping on the toes of other queued triggers.
1027 //
1028 function QueuedTriggerRemoveBJ takes trigger trig returns nothing
1029 local integer index
1030 local integer trigIndex
1031 local boolean trigExecuted
1032
1033 // Find the trigger's index.
1034 set trigIndex = QueuedTriggerGetIndex(trig)
1035 if (trigIndex == -1) then
1036 return
1037 endif
1038
1039 // Shuffle the other trigger entries down to fill in the gap.
1040 call QueuedTriggerRemoveByIndex(trigIndex)
1041
1042 // If we just axed the currently running trigger, run the next one.
1043 if (trigIndex == 0) then
1044 call PauseTimer(bj_queuedExecTimeoutTimer)
1045 call QueuedTriggerAttemptExec()
1046 endif
1047 endfunction
1048
1049 //===========================================================================
1050 // Denotes the end of a queued trigger. Be sure to call this only once per
1051 // queued trigger, lest you step on the toes of other queued triggers.
1052 //
1053 function QueuedTriggerDoneBJ takes nothing returns nothing
1054 local integer index
1055
1056 // Make sure there's something on the queue to remove.
1057 if (bj_queuedExecTotal <= 0) then
1058 return
1059 endif
1060
1061 // Remove the currently running trigger from the array.
1062 call QueuedTriggerRemoveByIndex(0)
1063
1064 // If other triggers are waiting to run, run one of them.
1065 call PauseTimer(bj_queuedExecTimeoutTimer)
1066 call QueuedTriggerAttemptExec()
1067 endfunction
1068
1069 //===========================================================================
1070 // Empty the trigger queue.
1071 //
1072 function QueuedTriggerClearBJ takes nothing returns nothing
1073 call PauseTimer(bj_queuedExecTimeoutTimer)
1074 set bj_queuedExecTotal = 0
1075 endfunction
1076
1077 //===========================================================================
1078 // Remove all but the currently executing trigger from the trigger queue.
1079 //
1080 function QueuedTriggerClearInactiveBJ takes nothing returns nothing
1081 set bj_queuedExecTotal = IMinBJ(bj_queuedExecTotal, 1)
1082 endfunction
1083
1084 //===========================================================================
1085 function QueuedTriggerCountBJ takes nothing returns integer
1086 return bj_queuedExecTotal
1087 endfunction
1088
1089 //===========================================================================
1090 function IsTriggerQueueEmptyBJ takes nothing returns boolean
1091 return bj_queuedExecTotal <= 0
1092 endfunction
1093
1094 //===========================================================================
1095 function IsTriggerQueuedBJ takes trigger trig returns boolean
1096 return QueuedTriggerGetIndex(trig) != -1
1097 endfunction
1098
1099 //===========================================================================
1100 function GetForLoopIndexA takes nothing returns integer
1101 return bj_forLoopAIndex
1102 endfunction
1103
1104 //===========================================================================
1105 function SetForLoopIndexA takes integer newIndex returns nothing
1106 set bj_forLoopAIndex = newIndex
1107 endfunction
1108
1109 //===========================================================================
1110 function GetForLoopIndexB takes nothing returns integer
1111 return bj_forLoopBIndex
1112 endfunction
1113
1114 //===========================================================================
1115 function SetForLoopIndexB takes integer newIndex returns nothing
1116 set bj_forLoopBIndex = newIndex
1117 endfunction
1118
1119 //===========================================================================
1120 // We can't do game-time waits, so this simulates one by starting a timer
1121 // and polling until the timer expires.
1122 function PolledWait takes real duration returns nothing
1123 local timer t
1124 local real timeRemaining
1125
1126 if (duration > 0) then
1127 set t = CreateTimer()
1128 call TimerStart(t, duration, false, null)
1129 loop
1130 set timeRemaining = TimerGetRemaining(t)
1131 exitwhen timeRemaining <= 0
1132
1133 // If we have a bit of time left, skip past 10% of the remaining
1134 // duration instead of checking every interval, to minimize the
1135 // polling on long waits.
1136 if (timeRemaining > bj_POLLED_WAIT_SKIP_THRESHOLD) then
1137 call TriggerSleepAction(0.1 * timeRemaining)
1138 else
1139 call TriggerSleepAction(bj_POLLED_WAIT_INTERVAL)
1140 endif
1141 endloop
1142 call DestroyTimer(t)
1143 endif
1144 endfunction
1145
1146 //===========================================================================
1147 function IntegerTertiaryOp takes boolean flag, integer valueA, integer valueB returns integer
1148 if flag then
1149 return valueA
1150 else
1151 return valueB
1152 endif
1153 endfunction
1154
1155
1156 //***************************************************************************
1157 //*
1158 //* General Utility Functions
1159 //* These functions exist purely to make the trigger dialogs cleaner and
1160 //* more comprehensible.
1161 //*
1162 //***************************************************************************
1163
1164 //===========================================================================
1165 function DoNothing takes nothing returns nothing
1166 endfunction
1167
1168 //===========================================================================
1169 // This function does nothing. WorldEdit should should eventually ignore
1170 // CommentString triggers during script generation, but until such a time,
1171 // this function will serve as a stub.
1172 //
1173 function CommentString takes string commentString returns nothing
1174 endfunction
1175
1176 //===========================================================================
1177 // This function returns the input string, converting it from the localized text, if necessary
1178 //
1179 function StringIdentity takes string theString returns string
1180 return GetLocalizedString(theString)
1181 endfunction
1182
1183 //===========================================================================
1184 function GetBooleanAnd takes boolean valueA, boolean valueB returns boolean
1185 return valueA and valueB
1186 endfunction
1187
1188 //===========================================================================
1189 function GetBooleanOr takes boolean valueA, boolean valueB returns boolean
1190 return valueA or valueB
1191 endfunction
1192
1193 //===========================================================================
1194 // Converts a percentage (real, 0..100) into a scaled integer (0..max),
1195 // clipping the result to 0..max in case the input is invalid.
1196 //
1197 function PercentToInt takes real percentage, integer max returns integer
1198 local integer result = R2I(percentage * I2R(max) * 0.01)
1199
1200 if (result < 0) then
1201 set result = 0
1202 elseif (result > max) then
1203 set result = max
1204 endif
1205
1206 return result
1207 endfunction
1208
1209 //===========================================================================
1210 function PercentTo255 takes real percentage returns integer
1211 return PercentToInt(percentage, 255)
1212 endfunction
1213
1214 //===========================================================================
1215 function GetTimeOfDay takes nothing returns real
1216 return GetFloatGameState(GAME_STATE_TIME_OF_DAY)
1217 endfunction
1218
1219 //===========================================================================
1220 function SetTimeOfDay takes real whatTime returns nothing
1221 call SetFloatGameState(GAME_STATE_TIME_OF_DAY, whatTime)
1222 endfunction
1223
1224 //===========================================================================
1225 function SetTimeOfDayScalePercentBJ takes real scalePercent returns nothing
1226 call SetTimeOfDayScale(scalePercent * 0.01)
1227 endfunction
1228
1229 //===========================================================================
1230 function GetTimeOfDayScalePercentBJ takes nothing returns real
1231 return GetTimeOfDayScale() * 100
1232 endfunction
1233
1234 //===========================================================================
1235 function PlaySound takes string soundName returns nothing
1236 local sound soundHandle = CreateSound(soundName, false, false, true, 12700, 12700, "")
1237 call StartSound(soundHandle)
1238 call KillSoundWhenDone(soundHandle)
1239 endfunction
1240
1241 //===========================================================================
1242 function CompareLocationsBJ takes location A, location B returns boolean
1243 return GetLocationX(A) == GetLocationX(B) and GetLocationY(A) == GetLocationY(B)
1244 endfunction
1245
1246 //===========================================================================
1247 function CompareRectsBJ takes rect A, rect B returns boolean
1248 return GetRectMinX(A) == GetRectMinX(B) and GetRectMinY(A) == GetRectMinY(B) and GetRectMaxX(A) == GetRectMaxX(B) and GetRectMaxY(A) == GetRectMaxY(B)
1249 endfunction
1250
1251 //===========================================================================
1252 // Returns a square rect that exactly encompasses the specified circle.
1253 //
1254 function GetRectFromCircleBJ takes location center, real radius returns rect
1255 local real centerX = GetLocationX(center)
1256 local real centerY = GetLocationY(center)
1257 return Rect(centerX - radius, centerY - radius, centerX + radius, centerY + radius)
1258 endfunction
1259
1260
1261
1262 //***************************************************************************
1263 //*
1264 //* Camera Utility Functions
1265 //*
1266 //***************************************************************************
1267
1268 //===========================================================================
1269 function GetCurrentCameraSetup takes nothing returns camerasetup
1270 local camerasetup theCam = CreateCameraSetup()
1271 local real duration = 0
1272 call CameraSetupSetField(theCam, CAMERA_FIELD_TARGET_DISTANCE, GetCameraField(CAMERA_FIELD_TARGET_DISTANCE), duration)
1273 call CameraSetupSetField(theCam, CAMERA_FIELD_FARZ, GetCameraField(CAMERA_FIELD_FARZ), duration)
1274 call CameraSetupSetField(theCam, CAMERA_FIELD_ZOFFSET, GetCameraField(CAMERA_FIELD_ZOFFSET), duration)
1275 call CameraSetupSetField(theCam, CAMERA_FIELD_ANGLE_OF_ATTACK, bj_RADTODEG * GetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK), duration)
1276 call CameraSetupSetField(theCam, CAMERA_FIELD_FIELD_OF_VIEW, bj_RADTODEG * GetCameraField(CAMERA_FIELD_FIELD_OF_VIEW), duration)
1277 call CameraSetupSetField(theCam, CAMERA_FIELD_ROLL, bj_RADTODEG * GetCameraField(CAMERA_FIELD_ROLL), duration)
1278 call CameraSetupSetField(theCam, CAMERA_FIELD_ROTATION, bj_RADTODEG * GetCameraField(CAMERA_FIELD_ROTATION), duration)
1279 call CameraSetupSetDestPosition(theCam, GetCameraTargetPositionX(), GetCameraTargetPositionY(), duration)
1280 return theCam
1281 endfunction
1282
1283 //===========================================================================
1284 function CameraSetupApplyForPlayer takes boolean doPan, camerasetup whichSetup, player whichPlayer, real duration returns nothing
1285 if (GetLocalPlayer() == whichPlayer) then
1286 // Use only local code (no net traffic) within this block to avoid desyncs.
1287 call CameraSetupApplyForceDuration(whichSetup, doPan, duration)
1288 endif
1289 endfunction
1290
1291 //===========================================================================
1292 function CameraSetupGetFieldSwap takes camerafield whichField, camerasetup whichSetup returns real
1293 return CameraSetupGetField(whichSetup, whichField)
1294 endfunction
1295
1296 //===========================================================================
1297 function SetCameraFieldForPlayer takes player whichPlayer, camerafield whichField, real value, real duration returns nothing
1298 if (GetLocalPlayer() == whichPlayer) then
1299 // Use only local code (no net traffic) within this block to avoid desyncs.
1300 call SetCameraField(whichField, value, duration)
1301 endif
1302 endfunction
1303
1304 //===========================================================================
1305 function SetCameraTargetControllerNoZForPlayer takes player whichPlayer, unit whichUnit, real xoffset, real yoffset, boolean inheritOrientation returns nothing
1306 if (GetLocalPlayer() == whichPlayer) then
1307 // Use only local code (no net traffic) within this block to avoid desyncs.
1308 call SetCameraTargetController(whichUnit, xoffset, yoffset, inheritOrientation)
1309 endif
1310 endfunction
1311
1312 //===========================================================================
1313 function SetCameraPositionForPlayer takes player whichPlayer, real x, real y returns nothing
1314 if (GetLocalPlayer() == whichPlayer) then
1315 // Use only local code (no net traffic) within this block to avoid desyncs.
1316 call SetCameraPosition(x, y)
1317 endif
1318 endfunction
1319
1320 //===========================================================================
1321 function SetCameraPositionLocForPlayer takes player whichPlayer, location loc returns nothing
1322 if (GetLocalPlayer() == whichPlayer) then
1323 // Use only local code (no net traffic) within this block to avoid desyncs.
1324 call SetCameraPosition(GetLocationX(loc), GetLocationY(loc))
1325 endif
1326 endfunction
1327
1328 //===========================================================================
1329 function RotateCameraAroundLocBJ takes real degrees, location loc, player whichPlayer, real duration returns nothing
1330 if (GetLocalPlayer() == whichPlayer) then
1331 // Use only local code (no net traffic) within this block to avoid desyncs.
1332 call SetCameraRotateMode(GetLocationX(loc), GetLocationY(loc), bj_DEGTORAD * degrees, duration)
1333 endif
1334 endfunction
1335
1336 //===========================================================================
1337 function PanCameraToForPlayer takes player whichPlayer, real x, real y returns nothing
1338 if (GetLocalPlayer() == whichPlayer) then
1339 // Use only local code (no net traffic) within this block to avoid desyncs.
1340 call PanCameraTo(x, y)
1341 endif
1342 endfunction
1343
1344 //===========================================================================
1345 function PanCameraToLocForPlayer takes player whichPlayer, location loc returns nothing
1346 if (GetLocalPlayer() == whichPlayer) then
1347 // Use only local code (no net traffic) within this block to avoid desyncs.
1348 call PanCameraTo(GetLocationX(loc), GetLocationY(loc))
1349 endif
1350 endfunction
1351
1352 //===========================================================================
1353 function PanCameraToTimedForPlayer takes player whichPlayer, real x, real y, real duration returns nothing
1354 if (GetLocalPlayer() == whichPlayer) then
1355 // Use only local code (no net traffic) within this block to avoid desyncs.
1356 call PanCameraToTimed(x, y, duration)
1357 endif
1358 endfunction
1359
1360 //===========================================================================
1361 function PanCameraToTimedLocForPlayer takes player whichPlayer, location loc, real duration returns nothing
1362 if (GetLocalPlayer() == whichPlayer) then
1363 // Use only local code (no net traffic) within this block to avoid desyncs.
1364 call PanCameraToTimed(GetLocationX(loc), GetLocationY(loc), duration)
1365 endif
1366 endfunction
1367
1368 //===========================================================================
1369 function PanCameraToTimedLocWithZForPlayer takes player whichPlayer, location loc, real zOffset, real duration returns nothing
1370 if (GetLocalPlayer() == whichPlayer) then
1371 // Use only local code (no net traffic) within this block to avoid desyncs.
1372 call PanCameraToTimedWithZ(GetLocationX(loc), GetLocationY(loc), zOffset, duration)
1373 endif
1374 endfunction
1375
1376 //===========================================================================
1377 function SmartCameraPanBJ takes player whichPlayer, location loc, real duration returns nothing
1378 local real dist
1379 if (GetLocalPlayer() == whichPlayer) then
1380 // Use only local code (no net traffic) within this block to avoid desyncs.
1381
1382 set dist = DistanceBetweenPoints(loc, GetCameraTargetPositionLoc())
1383 if (dist >= bj_SMARTPAN_TRESHOLD_SNAP) then
1384 // If the user is too far away, snap the camera.
1385 call PanCameraToTimed(GetLocationX(loc), GetLocationY(loc), 0)
1386 elseif (dist >= bj_SMARTPAN_TRESHOLD_PAN) then
1387 // If the user is moderately close, pan the camera.
1388 call PanCameraToTimed(GetLocationX(loc), GetLocationY(loc), duration)
1389 else
1390 // User is close enough, so don't touch the camera.
1391 endif
1392 endif
1393 endfunction
1394
1395 //===========================================================================
1396 function SetCinematicCameraForPlayer takes player whichPlayer, string cameraModelFile returns nothing
1397 if (GetLocalPlayer() == whichPlayer) then
1398 // Use only local code (no net traffic) within this block to avoid desyncs.
1399 call SetCinematicCamera(cameraModelFile)
1400 endif
1401 endfunction
1402
1403 //===========================================================================
1404 function ResetToGameCameraForPlayer takes player whichPlayer, real duration returns nothing
1405 if (GetLocalPlayer() == whichPlayer) then
1406 // Use only local code (no net traffic) within this block to avoid desyncs.
1407 call ResetToGameCamera(duration)
1408 endif
1409 endfunction
1410
1411 //===========================================================================
1412 function CameraSetSourceNoiseForPlayer takes player whichPlayer, real magnitude, real velocity returns nothing
1413 if (GetLocalPlayer() == whichPlayer) then
1414 // Use only local code (no net traffic) within this block to avoid desyncs.
1415 call CameraSetSourceNoise(magnitude, velocity)
1416 endif
1417 endfunction
1418
1419 //===========================================================================
1420 function CameraSetTargetNoiseForPlayer takes player whichPlayer, real magnitude, real velocity returns nothing
1421 if (GetLocalPlayer() == whichPlayer) then
1422 // Use only local code (no net traffic) within this block to avoid desyncs.
1423 call CameraSetTargetNoise(magnitude, velocity)
1424 endif
1425 endfunction
1426
1427 //===========================================================================
1428 function CameraSetEQNoiseForPlayer takes player whichPlayer, real magnitude returns nothing
1429 local real richter = magnitude
1430 if (richter > 5.0) then
1431 set richter = 5.0
1432 endif
1433 if (richter < 2.0) then
1434 set richter = 2.0
1435 endif
1436 if (GetLocalPlayer() == whichPlayer) then
1437 // Use only local code (no net traffic) within this block to avoid desyncs.
1438 call CameraSetTargetNoiseEx(magnitude*2.0, magnitude*Pow(10,richter),true)
1439 call CameraSetSourceNoiseEx(magnitude*2.0, magnitude*Pow(10,richter),true)
1440 endif
1441 endfunction
1442
1443 //===========================================================================
1444 function CameraClearNoiseForPlayer takes player whichPlayer returns nothing
1445 if (GetLocalPlayer() == whichPlayer) then
1446 // Use only local code (no net traffic) within this block to avoid desyncs.
1447 call CameraSetSourceNoise(0, 0)
1448 call CameraSetTargetNoise(0, 0)
1449 endif
1450 endfunction
1451
1452 //===========================================================================
1453 // Query the current camera bounds.
1454 //
1455 function GetCurrentCameraBoundsMapRectBJ takes nothing returns rect
1456 return Rect(GetCameraBoundMinX(), GetCameraBoundMinY(), GetCameraBoundMaxX(), GetCameraBoundMaxY())
1457 endfunction
1458
1459 //===========================================================================
1460 // Query the initial camera bounds, as defined at map init.
1461 //
1462 function GetCameraBoundsMapRect takes nothing returns rect
1463 return bj_mapInitialCameraBounds
1464 endfunction
1465
1466 //===========================================================================
1467 // Query the playable map area, as defined at map init.
1468 //
1469 function GetPlayableMapRect takes nothing returns rect
1470 return bj_mapInitialPlayableArea
1471 endfunction
1472
1473 //===========================================================================
1474 // Query the entire map area, as defined at map init.
1475 //
1476 function GetEntireMapRect takes nothing returns rect
1477 return GetWorldBounds()
1478 endfunction
1479
1480 //===========================================================================
1481 function SetCameraBoundsToRect takes rect r returns nothing
1482 local real minX = GetRectMinX(r)
1483 local real minY = GetRectMinY(r)
1484 local real maxX = GetRectMaxX(r)
1485 local real maxY = GetRectMaxY(r)
1486 call SetCameraBounds(minX, minY, minX, maxY, maxX, maxY, maxX, minY)
1487 endfunction
1488
1489 //===========================================================================
1490 function SetCameraBoundsToRectForPlayerBJ takes player whichPlayer, rect r returns nothing
1491 if (GetLocalPlayer() == whichPlayer) then
1492 // Use only local code (no net traffic) within this block to avoid desyncs.
1493 call SetCameraBoundsToRect(r)
1494 endif
1495 endfunction
1496
1497 //===========================================================================
1498 function AdjustCameraBoundsBJ takes integer adjustMethod, real dxWest, real dxEast, real dyNorth, real dySouth returns nothing
1499 local real minX = 0
1500 local real minY = 0
1501 local real maxX = 0
1502 local real maxY = 0
1503 local real scale = 0
1504
1505 if (adjustMethod == bj_CAMERABOUNDS_ADJUST_ADD) then
1506 set scale = 1
1507 elseif (adjustMethod == bj_CAMERABOUNDS_ADJUST_SUB) then
1508 set scale = -1
1509 else
1510 // Unrecognized adjustment method - ignore the request.
1511 return
1512 endif
1513
1514 // Adjust the actual camera values
1515 set minX = GetCameraBoundMinX() - scale * dxWest
1516 set maxX = GetCameraBoundMaxX() + scale * dxEast
1517 set minY = GetCameraBoundMinY() - scale * dySouth
1518 set maxY = GetCameraBoundMaxY() + scale * dyNorth
1519
1520 // Make sure the camera bounds are still valid.
1521 if (maxX < minX) then
1522 set minX = (minX + maxX) * 0.5
1523 set maxX = minX
1524 endif
1525 if (maxY < minY) then
1526 set minY = (minY + maxY) * 0.5
1527 set maxY = minY
1528 endif
1529
1530 // Apply the new camera values.
1531 call SetCameraBounds(minX, minY, minX, maxY, maxX, maxY, maxX, minY)
1532 endfunction
1533
1534 //===========================================================================
1535 function AdjustCameraBoundsForPlayerBJ takes integer adjustMethod, player whichPlayer, real dxWest, real dxEast, real dyNorth, real dySouth returns nothing
1536 if (GetLocalPlayer() == whichPlayer) then
1537 // Use only local code (no net traffic) within this block to avoid desyncs.
1538 call AdjustCameraBoundsBJ(adjustMethod, dxWest, dxEast, dyNorth, dySouth)
1539 endif
1540 endfunction
1541
1542 //===========================================================================
1543 function SetCameraQuickPositionForPlayer takes player whichPlayer, real x, real y returns nothing
1544 if (GetLocalPlayer() == whichPlayer) then
1545 // Use only local code (no net traffic) within this block to avoid desyncs.
1546 call SetCameraQuickPosition(x, y)
1547 endif
1548 endfunction
1549
1550 //===========================================================================
1551 function SetCameraQuickPositionLocForPlayer takes player whichPlayer, location loc returns nothing
1552 if (GetLocalPlayer() == whichPlayer) then
1553 // Use only local code (no net traffic) within this block to avoid desyncs.
1554 call SetCameraQuickPosition(GetLocationX(loc), GetLocationY(loc))
1555 endif
1556 endfunction
1557
1558 //===========================================================================
1559 function SetCameraQuickPositionLoc takes location loc returns nothing
1560 call SetCameraQuickPosition(GetLocationX(loc), GetLocationY(loc))
1561 endfunction
1562
1563 //===========================================================================
1564 function StopCameraForPlayerBJ takes player whichPlayer returns nothing
1565 if (GetLocalPlayer() == whichPlayer) then
1566 // Use only local code (no net traffic) within this block to avoid desyncs.
1567 call StopCamera()
1568 endif
1569 endfunction
1570
1571 //===========================================================================
1572 function SetCameraOrientControllerForPlayerBJ takes player whichPlayer, unit whichUnit, real xoffset, real yoffset returns nothing
1573 if (GetLocalPlayer() == whichPlayer) then
1574 // Use only local code (no net traffic) within this block to avoid desyncs.
1575 call SetCameraOrientController(whichUnit, xoffset, yoffset)
1576 endif
1577 endfunction
1578
1579 //===========================================================================
1580 function CameraSetSmoothingFactorBJ takes real factor returns nothing
1581 call CameraSetSmoothingFactor(factor)
1582 endfunction
1583
1584 //===========================================================================
1585 function CameraResetSmoothingFactorBJ takes nothing returns nothing
1586 call CameraSetSmoothingFactor(0)
1587 endfunction
1588
1589
1590
1591 //***************************************************************************
1592 //*
1593 //* Text Utility Functions
1594 //*
1595 //***************************************************************************
1596
1597 //===========================================================================
1598 function DisplayTextToForce takes force toForce, string message returns nothing
1599 if (IsPlayerInForce(GetLocalPlayer(), toForce)) then
1600 // Use only local code (no net traffic) within this block to avoid desyncs.
1601 call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, message)
1602 endif
1603 endfunction
1604
1605 //===========================================================================
1606 function DisplayTimedTextToForce takes force toForce, real duration, string message returns nothing
1607 if (IsPlayerInForce(GetLocalPlayer(), toForce)) then
1608 // Use only local code (no net traffic) within this block to avoid desyncs.
1609 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, duration, message)
1610 endif
1611 endfunction
1612
1613 //===========================================================================
1614 function ClearTextMessagesBJ takes force toForce returns nothing
1615 if (IsPlayerInForce(GetLocalPlayer(), toForce)) then
1616 // Use only local code (no net traffic) within this block to avoid desyncs.
1617 call ClearTextMessages()
1618 endif
1619 endfunction
1620
1621 //===========================================================================
1622 // The parameters for the API Substring function are unintuitive, so this
1623 // merely performs a translation for the starting index.
1624 //
1625 function SubStringBJ takes string source, integer start, integer end returns string
1626 return SubString(source, start-1, end)
1627 endfunction
1628
1629
1630
1631 //***************************************************************************
1632 //*
1633 //* Event Registration Utility Functions
1634 //*
1635 //***************************************************************************
1636
1637 //===========================================================================
1638 function TriggerRegisterTimerEventPeriodic takes trigger trig, real timeout returns event
1639 return TriggerRegisterTimerEvent(trig, timeout, true)
1640 endfunction
1641
1642 //===========================================================================
1643 function TriggerRegisterTimerEventSingle takes trigger trig, real timeout returns event
1644 return TriggerRegisterTimerEvent(trig, timeout, false)
1645 endfunction
1646
1647 //===========================================================================
1648 function TriggerRegisterTimerExpireEventBJ takes trigger trig, timer t returns event
1649 return TriggerRegisterTimerExpireEvent(trig, t)
1650 endfunction
1651
1652 //===========================================================================
1653 function TriggerRegisterPlayerUnitEventSimple takes trigger trig, player whichPlayer, playerunitevent whichEvent returns event
1654 return TriggerRegisterPlayerUnitEvent(trig, whichPlayer, whichEvent, null)
1655 endfunction
1656
1657 //===========================================================================
1658 function TriggerRegisterAnyUnitEventBJ takes trigger trig, playerunitevent whichEvent returns nothing
1659 local integer index
1660
1661 set index = 0
1662 loop
1663 call TriggerRegisterPlayerUnitEvent(trig, Player(index), whichEvent, null)
1664
1665 set index = index + 1
1666 exitwhen index == bj_MAX_PLAYER_SLOTS
1667 endloop
1668 endfunction
1669
1670 //===========================================================================
1671 function TriggerRegisterPlayerSelectionEventBJ takes trigger trig, player whichPlayer, boolean selected returns event
1672 if selected then
1673 return TriggerRegisterPlayerUnitEvent(trig, whichPlayer, EVENT_PLAYER_UNIT_SELECTED, null)
1674 else
1675 return TriggerRegisterPlayerUnitEvent(trig, whichPlayer, EVENT_PLAYER_UNIT_DESELECTED, null)
1676 endif
1677 endfunction
1678
1679 //===========================================================================
1680 function TriggerRegisterPlayerKeyEventBJ takes trigger trig, player whichPlayer, integer keType, integer keKey returns event
1681 if (keType == bj_KEYEVENTTYPE_DEPRESS) then
1682 // Depress event - find out what key
1683 if (keKey == bj_KEYEVENTKEY_LEFT) then
1684 return TriggerRegisterPlayerEvent(trig, whichPlayer, EVENT_PLAYER_ARROW_LEFT_DOWN)
1685 elseif (keKey == bj_KEYEVENTKEY_RIGHT) then
1686 return TriggerRegisterPlayerEvent(trig, whichPlayer, EVENT_PLAYER_ARROW_RIGHT_DOWN)
1687 elseif (keKey == bj_KEYEVENTKEY_DOWN) then
1688 return TriggerRegisterPlayerEvent(trig, whichPlayer, EVENT_PLAYER_ARROW_DOWN_DOWN)
1689 elseif (keKey == bj_KEYEVENTKEY_UP) then
1690 return TriggerRegisterPlayerEvent(trig, whichPlayer, EVENT_PLAYER_ARROW_UP_DOWN)
1691 else
1692 // Unrecognized key - ignore the request and return failure.
1693 return null
1694 endif
1695 elseif (keType == bj_KEYEVENTTYPE_RELEASE) then
1696 // Release event - find out what key
1697 if (keKey == bj_KEYEVENTKEY_LEFT) then
1698 return TriggerRegisterPlayerEvent(trig, whichPlayer, EVENT_PLAYER_ARROW_LEFT_UP)
1699 elseif (keKey == bj_KEYEVENTKEY_RIGHT) then
1700 return TriggerRegisterPlayerEvent(trig, whichPlayer, EVENT_PLAYER_ARROW_RIGHT_UP)
1701 elseif (keKey == bj_KEYEVENTKEY_DOWN) then
1702 return TriggerRegisterPlayerEvent(trig, whichPlayer, EVENT_PLAYER_ARROW_DOWN_UP)
1703 elseif (keKey == bj_KEYEVENTKEY_UP) then
1704 return TriggerRegisterPlayerEvent(trig, whichPlayer, EVENT_PLAYER_ARROW_UP_UP)
1705 else
1706 // Unrecognized key - ignore the request and return failure.
1707 return null
1708 endif
1709 else
1710 // Unrecognized type - ignore the request and return failure.
1711 return null
1712 endif
1713 endfunction
1714
1715 //===========================================================================
1716 function TriggerRegisterPlayerEventVictory takes trigger trig, player whichPlayer returns event
1717 return TriggerRegisterPlayerEvent(trig, whichPlayer, EVENT_PLAYER_VICTORY)
1718 endfunction
1719
1720 //===========================================================================
1721 function TriggerRegisterPlayerEventDefeat takes trigger trig, player whichPlayer returns event
1722 return TriggerRegisterPlayerEvent(trig, whichPlayer, EVENT_PLAYER_DEFEAT)
1723 endfunction
1724
1725 //===========================================================================
1726 function TriggerRegisterPlayerEventLeave takes trigger trig, player whichPlayer returns event
1727 return TriggerRegisterPlayerEvent(trig, whichPlayer, EVENT_PLAYER_LEAVE)
1728 endfunction
1729
1730 //===========================================================================
1731 function TriggerRegisterPlayerEventAllianceChanged takes trigger trig, player whichPlayer returns event
1732 return TriggerRegisterPlayerEvent(trig, whichPlayer, EVENT_PLAYER_ALLIANCE_CHANGED)
1733 endfunction
1734
1735 //===========================================================================
1736 function TriggerRegisterPlayerEventEndCinematic takes trigger trig, player whichPlayer returns event
1737 return TriggerRegisterPlayerEvent(trig, whichPlayer, EVENT_PLAYER_END_CINEMATIC)
1738 endfunction
1739
1740 //===========================================================================
1741 function TriggerRegisterGameStateEventTimeOfDay takes trigger trig, limitop opcode, real limitval returns event
1742 return TriggerRegisterGameStateEvent(trig, GAME_STATE_TIME_OF_DAY, opcode, limitval)
1743 endfunction
1744
1745 //===========================================================================
1746 function TriggerRegisterEnterRegionSimple takes trigger trig, region whichRegion returns event
1747 return TriggerRegisterEnterRegion(trig, whichRegion, null)
1748 endfunction
1749
1750 //===========================================================================
1751 function TriggerRegisterLeaveRegionSimple takes trigger trig, region whichRegion returns event
1752 return TriggerRegisterLeaveRegion(trig, whichRegion, null)
1753 endfunction
1754
1755 //===========================================================================
1756 function TriggerRegisterEnterRectSimple takes trigger trig, rect r returns event
1757 local region rectRegion = CreateRegion()
1758 call RegionAddRect(rectRegion, r)
1759 return TriggerRegisterEnterRegion(trig, rectRegion, null)
1760 endfunction
1761
1762 //===========================================================================
1763 function TriggerRegisterLeaveRectSimple takes trigger trig, rect r returns event
1764 local region rectRegion = CreateRegion()
1765 call RegionAddRect(rectRegion, r)
1766 return TriggerRegisterLeaveRegion(trig, rectRegion, null)
1767 endfunction
1768
1769 //===========================================================================
1770 function TriggerRegisterDistanceBetweenUnits takes trigger trig, unit whichUnit, boolexpr condition, real range returns event
1771 return TriggerRegisterUnitInRange(trig, whichUnit, range, condition)
1772 endfunction
1773
1774 //===========================================================================
1775 function TriggerRegisterUnitInRangeSimple takes trigger trig, real range, unit whichUnit returns event
1776 return TriggerRegisterUnitInRange(trig, whichUnit, range, null)
1777 endfunction
1778
1779 //===========================================================================
1780 function TriggerRegisterUnitLifeEvent takes trigger trig, unit whichUnit, limitop opcode, real limitval returns event
1781 return TriggerRegisterUnitStateEvent(trig, whichUnit, UNIT_STATE_LIFE, opcode, limitval)
1782 endfunction
1783
1784 //===========================================================================
1785 function TriggerRegisterUnitManaEvent takes trigger trig, unit whichUnit, limitop opcode, real limitval returns event
1786 return TriggerRegisterUnitStateEvent(trig, whichUnit, UNIT_STATE_MANA, opcode, limitval)
1787 endfunction
1788
1789 //===========================================================================
1790 function TriggerRegisterDialogEventBJ takes trigger trig, dialog whichDialog returns event
1791 return TriggerRegisterDialogEvent(trig, whichDialog)
1792 endfunction
1793
1794 //===========================================================================
1795 function TriggerRegisterShowSkillEventBJ takes trigger trig returns event
1796 return TriggerRegisterGameEvent(trig, EVENT_GAME_SHOW_SKILL)
1797 endfunction
1798
1799 //===========================================================================
1800 function TriggerRegisterBuildSubmenuEventBJ takes trigger trig returns event
1801 return TriggerRegisterGameEvent(trig, EVENT_GAME_BUILD_SUBMENU)
1802 endfunction
1803
1804 //===========================================================================
1805 function TriggerRegisterGameLoadedEventBJ takes trigger trig returns event
1806 return TriggerRegisterGameEvent(trig, EVENT_GAME_LOADED)
1807 endfunction
1808
1809 //===========================================================================
1810 function TriggerRegisterGameSavedEventBJ takes trigger trig returns event
1811 return TriggerRegisterGameEvent(trig, EVENT_GAME_SAVE)
1812 endfunction
1813
1814 //===========================================================================
1815 function RegisterDestDeathInRegionEnum takes nothing returns nothing
1816 set bj_destInRegionDiesCount = bj_destInRegionDiesCount + 1
1817 if (bj_destInRegionDiesCount <= bj_MAX_DEST_IN_REGION_EVENTS) then
1818 call TriggerRegisterDeathEvent(bj_destInRegionDiesTrig, GetEnumDestructable())
1819 endif
1820 endfunction
1821
1822 //===========================================================================
1823 function TriggerRegisterDestDeathInRegionEvent takes trigger trig, rect r returns event
1824 set bj_destInRegionDiesTrig = trig
1825 set bj_destInRegionDiesCount = 0
1826 call EnumDestructablesInRect(r, null, function RegisterDestDeathInRegionEnum)
1827 return trig
1828 endfunction
1829
1830
1831
1832 //***************************************************************************
1833 //*
1834 //* Environment Utility Functions
1835 //*
1836 //***************************************************************************
1837
1838 //===========================================================================
1839 function AddWeatherEffectSaveLast takes rect where, integer effectID returns weathereffect
1840 set bj_lastCreatedWeatherEffect = AddWeatherEffect(where, effectID)
1841 return bj_lastCreatedWeatherEffect
1842 endfunction
1843
1844 //===========================================================================
1845 function GetLastCreatedWeatherEffect takes nothing returns weathereffect
1846 return bj_lastCreatedWeatherEffect
1847 endfunction
1848
1849 //===========================================================================
1850 function RemoveWeatherEffectBJ takes weathereffect whichWeatherEffect returns nothing
1851 call RemoveWeatherEffect(whichWeatherEffect)
1852 endfunction
1853
1854 //===========================================================================
1855 function TerrainDeformationCraterBJ takes real duration, boolean permanent, location where, real radius, real depth returns terraindeformation
1856 set bj_lastCreatedTerrainDeformation = TerrainDeformCrater(GetLocationX(where), GetLocationY(where), radius, depth, R2I(duration * 1000), permanent)
1857 return bj_lastCreatedTerrainDeformation
1858 endfunction
1859
1860 //===========================================================================
1861 function TerrainDeformationRippleBJ takes real duration, boolean limitNeg, location where, real startRadius, real endRadius, real depth, real wavePeriod, real waveWidth returns terraindeformation
1862 local real spaceWave
1863 local real timeWave
1864 local real radiusRatio
1865
1866 if (endRadius <= 0 or waveWidth <= 0 or wavePeriod <= 0) then
1867 return null
1868 endif
1869
1870 set timeWave = 2.0 * duration / wavePeriod
1871 set spaceWave = 2.0 * endRadius / waveWidth
1872 set radiusRatio = startRadius / endRadius
1873
1874 set bj_lastCreatedTerrainDeformation = TerrainDeformRipple(GetLocationX(where), GetLocationY(where), endRadius, depth, R2I(duration * 1000), 1, spaceWave, timeWave, radiusRatio, limitNeg)
1875 return bj_lastCreatedTerrainDeformation
1876 endfunction
1877
1878 //===========================================================================
1879 function TerrainDeformationWaveBJ takes real duration, location source, location target, real radius, real depth, real trailDelay returns terraindeformation
1880 local real distance
1881 local real dirX
1882 local real dirY
1883 local real speed
1884
1885 set distance = DistanceBetweenPoints(source, target)
1886 if (distance == 0 or duration <= 0) then
1887 return null
1888 endif
1889
1890 set dirX = (GetLocationX(target) - GetLocationX(source)) / distance
1891 set dirY = (GetLocationY(target) - GetLocationY(source)) / distance
1892 set speed = distance / duration
1893
1894 set bj_lastCreatedTerrainDeformation = TerrainDeformWave(GetLocationX(source), GetLocationY(source), dirX, dirY, distance, speed, radius, depth, R2I(trailDelay * 1000), 1)
1895 return bj_lastCreatedTerrainDeformation
1896 endfunction
1897
1898 //===========================================================================
1899 function TerrainDeformationRandomBJ takes real duration, location where, real radius, real minDelta, real maxDelta, real updateInterval returns terraindeformation
1900 set bj_lastCreatedTerrainDeformation = TerrainDeformRandom(GetLocationX(where), GetLocationY(where), radius, minDelta, maxDelta, R2I(duration * 1000), R2I(updateInterval * 1000))
1901 return bj_lastCreatedTerrainDeformation
1902 endfunction
1903
1904 //===========================================================================
1905 function TerrainDeformationStopBJ takes terraindeformation deformation, real duration returns nothing
1906 call TerrainDeformStop(deformation, R2I(duration * 1000))
1907 endfunction
1908
1909 //===========================================================================
1910 function GetLastCreatedTerrainDeformation takes nothing returns terraindeformation
1911 return bj_lastCreatedTerrainDeformation
1912 endfunction
1913
1914 //===========================================================================
1915 function AddLightningLoc takes string codeName, location where1, location where2 returns lightning
1916 set bj_lastCreatedLightning = AddLightningEx(codeName, true, GetLocationX(where1), GetLocationY(where1), GetLocationZ(where1), GetLocationX(where2), GetLocationY(where2), GetLocationZ(where2))
1917 return bj_lastCreatedLightning
1918 endfunction
1919
1920 //===========================================================================
1921 function DestroyLightningBJ takes lightning whichBolt returns boolean
1922 return DestroyLightning(whichBolt)
1923 endfunction
1924
1925 //===========================================================================
1926 function MoveLightningLoc takes lightning whichBolt, location where1, location where2 returns boolean
1927 return MoveLightningEx(whichBolt, true, GetLocationX(where1), GetLocationY(where1), GetLocationZ(where1), GetLocationX(where2), GetLocationY(where2), GetLocationZ(where2))
1928 endfunction
1929
1930 //===========================================================================
1931 function GetLightningColorABJ takes lightning whichBolt returns real
1932 return GetLightningColorA(whichBolt)
1933 endfunction
1934
1935 //===========================================================================
1936 function GetLightningColorRBJ takes lightning whichBolt returns real
1937 return GetLightningColorR(whichBolt)
1938 endfunction
1939
1940 //===========================================================================
1941 function GetLightningColorGBJ takes lightning whichBolt returns real
1942 return GetLightningColorG(whichBolt)
1943 endfunction
1944
1945 //===========================================================================
1946 function GetLightningColorBBJ takes lightning whichBolt returns real
1947 return GetLightningColorB(whichBolt)
1948 endfunction
1949
1950 //===========================================================================
1951 function SetLightningColorBJ takes lightning whichBolt, real r, real g, real b, real a returns boolean
1952 return SetLightningColor(whichBolt, r, g, b, a)
1953 endfunction
1954
1955 //===========================================================================
1956 function GetLastCreatedLightningBJ takes nothing returns lightning
1957 return bj_lastCreatedLightning
1958 endfunction
1959
1960 //===========================================================================
1961 function GetAbilityEffectBJ takes integer abilcode, effecttype t, integer index returns string
1962 return GetAbilityEffectById(abilcode, t, index)
1963 endfunction
1964
1965 //===========================================================================
1966 function GetAbilitySoundBJ takes integer abilcode, soundtype t returns string
1967 return GetAbilitySoundById(abilcode, t)
1968 endfunction
1969
1970
1971 //===========================================================================
1972 function GetTerrainCliffLevelBJ takes location where returns integer
1973 return GetTerrainCliffLevel(GetLocationX(where), GetLocationY(where))
1974 endfunction
1975
1976 //===========================================================================
1977 function GetTerrainTypeBJ takes location where returns integer
1978 return GetTerrainType(GetLocationX(where), GetLocationY(where))
1979 endfunction
1980
1981 //===========================================================================
1982 function GetTerrainVarianceBJ takes location where returns integer
1983 return GetTerrainVariance(GetLocationX(where), GetLocationY(where))
1984 endfunction
1985
1986 //===========================================================================
1987 function SetTerrainTypeBJ takes location where, integer terrainType, integer variation, integer area, integer shape returns nothing
1988 call SetTerrainType(GetLocationX(where), GetLocationY(where), terrainType, variation, area, shape)
1989 endfunction
1990
1991 //===========================================================================
1992 function IsTerrainPathableBJ takes location where, pathingtype t returns boolean
1993 return IsTerrainPathable(GetLocationX(where), GetLocationY(where), t)
1994 endfunction
1995
1996 //===========================================================================
1997 function SetTerrainPathableBJ takes location where, pathingtype t, boolean flag returns nothing
1998 call SetTerrainPathable(GetLocationX(where), GetLocationY(where), t, flag)
1999 endfunction
2000
2001 //===========================================================================
2002 function SetWaterBaseColorBJ takes real red, real green, real blue, real transparency returns nothing
2003 call SetWaterBaseColor(PercentTo255(red), PercentTo255(green), PercentTo255(blue), PercentTo255(100.0-transparency))
2004 endfunction
2005
2006 //===========================================================================
2007 function CreateFogModifierRectSimple takes player whichPlayer, fogstate whichFogState, rect r, boolean afterUnits returns fogmodifier
2008 set bj_lastCreatedFogModifier = CreateFogModifierRect(whichPlayer, whichFogState, r, true, afterUnits)
2009 return bj_lastCreatedFogModifier
2010 endfunction
2011
2012 //===========================================================================
2013 function CreateFogModifierRadiusLocSimple takes player whichPlayer, fogstate whichFogState, location center, real radius, boolean afterUnits returns fogmodifier
2014 set bj_lastCreatedFogModifier = CreateFogModifierRadiusLoc(whichPlayer, whichFogState, center, radius, true, afterUnits)
2015 return bj_lastCreatedFogModifier
2016 endfunction
2017
2018 //===========================================================================
2019 // Version of CreateFogModifierRect that assumes use of sharedVision and
2020 // gives the option of immediately enabling the modifier, so that triggers
2021 // can default to modifiers that are immediately enabled.
2022 //
2023 function CreateFogModifierRectBJ takes boolean enabled, player whichPlayer, fogstate whichFogState, rect r returns fogmodifier
2024 set bj_lastCreatedFogModifier = CreateFogModifierRect(whichPlayer, whichFogState, r, true, false)
2025 if enabled then
2026 call FogModifierStart(bj_lastCreatedFogModifier)
2027 endif
2028 return bj_lastCreatedFogModifier
2029 endfunction
2030
2031 //===========================================================================
2032 // Version of CreateFogModifierRadius that assumes use of sharedVision and
2033 // gives the option of immediately enabling the modifier, so that triggers
2034 // can default to modifiers that are immediately enabled.
2035 //
2036 function CreateFogModifierRadiusLocBJ takes boolean enabled, player whichPlayer, fogstate whichFogState, location center, real radius returns fogmodifier
2037 set bj_lastCreatedFogModifier = CreateFogModifierRadiusLoc(whichPlayer, whichFogState, center, radius, true, false)
2038 if enabled then
2039 call FogModifierStart(bj_lastCreatedFogModifier)
2040 endif
2041 return bj_lastCreatedFogModifier
2042 endfunction
2043
2044 //===========================================================================
2045 function GetLastCreatedFogModifier takes nothing returns fogmodifier
2046 return bj_lastCreatedFogModifier
2047 endfunction
2048
2049 //===========================================================================
2050 function FogEnableOn takes nothing returns nothing
2051 call FogEnable(true)
2052 endfunction
2053
2054 //===========================================================================
2055 function FogEnableOff takes nothing returns nothing
2056 call FogEnable(false)
2057 endfunction
2058
2059 //===========================================================================
2060 function FogMaskEnableOn takes nothing returns nothing
2061 call FogMaskEnable(true)
2062 endfunction
2063
2064 //===========================================================================
2065 function FogMaskEnableOff takes nothing returns nothing
2066 call FogMaskEnable(false)
2067 endfunction
2068
2069 //===========================================================================
2070 function UseTimeOfDayBJ takes boolean flag returns nothing
2071 call SuspendTimeOfDay(not flag)
2072 endfunction
2073
2074 //===========================================================================
2075 function SetTerrainFogExBJ takes integer style, real zstart, real zend, real density, real red, real green, real blue returns nothing
2076 call SetTerrainFogEx(style, zstart, zend, density, red * 0.01, green * 0.01, blue * 0.01)
2077 endfunction
2078
2079 //===========================================================================
2080 function ResetTerrainFogBJ takes nothing returns nothing
2081 call ResetTerrainFog()
2082 endfunction
2083
2084 //===========================================================================
2085 function SetDoodadAnimationBJ takes string animName, integer doodadID, real radius, location center returns nothing
2086 call SetDoodadAnimation(GetLocationX(center), GetLocationY(center), radius, doodadID, false, animName, false)
2087 endfunction
2088
2089 //===========================================================================
2090 function SetDoodadAnimationRectBJ takes string animName, integer doodadID, rect r returns nothing
2091 call SetDoodadAnimationRect(r, doodadID, animName, false)
2092 endfunction
2093
2094 //===========================================================================
2095 function AddUnitAnimationPropertiesBJ takes boolean add, string animProperties, unit whichUnit returns nothing
2096 call AddUnitAnimationProperties(whichUnit, animProperties, add)
2097 endfunction
2098
2099
2100 //============================================================================
2101 function CreateImageBJ takes string file, real size, location where, real zOffset, integer imageType returns image
2102 set bj_lastCreatedImage = CreateImage(file, size, size, size, GetLocationX(where), GetLocationY(where), zOffset, 0, 0, 0, imageType)
2103 return bj_lastCreatedImage
2104 endfunction
2105
2106 //============================================================================
2107 function ShowImageBJ takes boolean flag, image whichImage returns nothing
2108 call ShowImage(whichImage, flag)
2109 endfunction
2110
2111 //============================================================================
2112 function SetImagePositionBJ takes image whichImage, location where, real zOffset returns nothing
2113 call SetImagePosition(whichImage, GetLocationX(where), GetLocationY(where), zOffset)
2114 endfunction
2115
2116 //============================================================================
2117 function SetImageColorBJ takes image whichImage, real red, real green, real blue, real alpha returns nothing
2118 call SetImageColor(whichImage, PercentTo255(red), PercentTo255(green), PercentTo255(blue), PercentTo255(100.0-alpha))
2119 endfunction
2120
2121 //============================================================================
2122 function GetLastCreatedImage takes nothing returns image
2123 return bj_lastCreatedImage
2124 endfunction
2125
2126 //============================================================================
2127 function CreateUbersplatBJ takes location where, string name, real red, real green, real blue, real alpha, boolean forcePaused, boolean noBirthTime returns ubersplat
2128 set bj_lastCreatedUbersplat = CreateUbersplat(GetLocationX(where), GetLocationY(where), name, PercentTo255(red), PercentTo255(green), PercentTo255(blue), PercentTo255(100.0-alpha), forcePaused, noBirthTime)
2129 return bj_lastCreatedUbersplat
2130 endfunction
2131
2132 //============================================================================
2133 function ShowUbersplatBJ takes boolean flag, ubersplat whichSplat returns nothing
2134 call ShowUbersplat(whichSplat, flag)
2135 endfunction
2136
2137 //============================================================================
2138 function GetLastCreatedUbersplat takes nothing returns ubersplat
2139 return bj_lastCreatedUbersplat
2140 endfunction
2141
2142
2143 //***************************************************************************
2144 //*
2145 //* Sound Utility Functions
2146 //*
2147 //***************************************************************************
2148
2149 //===========================================================================
2150 function PlaySoundBJ takes sound soundHandle returns nothing
2151 set bj_lastPlayedSound = soundHandle
2152 if (soundHandle != null) then
2153 call StartSound(soundHandle)
2154 endif
2155 endfunction
2156
2157 //===========================================================================
2158 function StopSoundBJ takes sound soundHandle, boolean fadeOut returns nothing
2159 call StopSound(soundHandle, false, fadeOut)
2160 endfunction
2161
2162 //===========================================================================
2163 function SetSoundVolumeBJ takes sound soundHandle, real volumePercent returns nothing
2164 call SetSoundVolume(soundHandle, PercentToInt(volumePercent, 127))
2165 endfunction
2166
2167 //===========================================================================
2168 function SetSoundOffsetBJ takes real newOffset, sound soundHandle returns nothing
2169 call SetSoundPlayPosition(soundHandle, R2I(newOffset * 1000))
2170 endfunction
2171
2172 //===========================================================================
2173 function SetSoundDistanceCutoffBJ takes sound soundHandle, real cutoff returns nothing
2174 call SetSoundDistanceCutoff(soundHandle, cutoff)
2175 endfunction
2176
2177 //===========================================================================
2178 function SetSoundPitchBJ takes sound soundHandle, real pitch returns nothing
2179 call SetSoundPitch(soundHandle, pitch)
2180 endfunction
2181
2182 //===========================================================================
2183 function SetSoundPositionLocBJ takes sound soundHandle, location loc, real z returns nothing
2184 call SetSoundPosition(soundHandle, GetLocationX(loc), GetLocationY(loc), z)
2185 endfunction
2186
2187 //===========================================================================
2188 function AttachSoundToUnitBJ takes sound soundHandle, unit whichUnit returns nothing
2189 call AttachSoundToUnit(soundHandle, whichUnit)
2190 endfunction
2191
2192 //===========================================================================
2193 function SetSoundConeAnglesBJ takes sound soundHandle, real inside, real outside, real outsideVolumePercent returns nothing
2194 call SetSoundConeAngles(soundHandle, inside, outside, PercentToInt(outsideVolumePercent, 127))
2195 endfunction
2196
2197 //===========================================================================
2198 function KillSoundWhenDoneBJ takes sound soundHandle returns nothing
2199 call KillSoundWhenDone(soundHandle)
2200 endfunction
2201
2202 //===========================================================================
2203 function PlaySoundAtPointBJ takes sound soundHandle, real volumePercent, location loc, real z returns nothing
2204 call SetSoundPositionLocBJ(soundHandle, loc, z)
2205 call SetSoundVolumeBJ(soundHandle, volumePercent)
2206 call PlaySoundBJ(soundHandle)
2207 endfunction
2208
2209 //===========================================================================
2210 function PlaySoundOnUnitBJ takes sound soundHandle, real volumePercent, unit whichUnit returns nothing
2211 call AttachSoundToUnitBJ(soundHandle, whichUnit)
2212 call SetSoundVolumeBJ(soundHandle, volumePercent)
2213 call PlaySoundBJ(soundHandle)
2214 endfunction
2215
2216 //===========================================================================
2217 function PlaySoundFromOffsetBJ takes sound soundHandle, real volumePercent, real startingOffset returns nothing
2218 call SetSoundVolumeBJ(soundHandle, volumePercent)
2219 call PlaySoundBJ(soundHandle)
2220 call SetSoundOffsetBJ(startingOffset, soundHandle)
2221 endfunction
2222
2223 //===========================================================================
2224 function PlayMusicBJ takes string musicFileName returns nothing
2225 set bj_lastPlayedMusic = musicFileName
2226 call PlayMusic(musicFileName)
2227 endfunction
2228
2229 //===========================================================================
2230 function PlayMusicExBJ takes string musicFileName, real startingOffset, real fadeInTime returns nothing
2231 set bj_lastPlayedMusic = musicFileName
2232 call PlayMusicEx(musicFileName, R2I(startingOffset * 1000), R2I(fadeInTime * 1000))
2233 endfunction
2234
2235 //===========================================================================
2236 function SetMusicOffsetBJ takes real newOffset returns nothing
2237 call SetMusicPlayPosition(R2I(newOffset * 1000))
2238 endfunction
2239
2240 //===========================================================================
2241 function PlayThematicMusicBJ takes string musicName returns nothing
2242 call PlayThematicMusic(musicName)
2243 endfunction
2244
2245 //===========================================================================
2246 function PlayThematicMusicExBJ takes string musicName, real startingOffset returns nothing
2247 call PlayThematicMusicEx(musicName, R2I(startingOffset * 1000))
2248 endfunction
2249
2250 //===========================================================================
2251 function SetThematicMusicOffsetBJ takes real newOffset returns nothing
2252 call SetThematicMusicPlayPosition(R2I(newOffset * 1000))
2253 endfunction
2254
2255 //===========================================================================
2256 function EndThematicMusicBJ takes nothing returns nothing
2257 call EndThematicMusic()
2258 endfunction
2259
2260 //===========================================================================
2261 function StopMusicBJ takes boolean fadeOut returns nothing
2262 call StopMusic(fadeOut)
2263 endfunction
2264
2265 //===========================================================================
2266 function ResumeMusicBJ takes nothing returns nothing
2267 call ResumeMusic()
2268 endfunction
2269
2270 //===========================================================================
2271 function SetMusicVolumeBJ takes real volumePercent returns nothing
2272 call SetMusicVolume(PercentToInt(volumePercent, 127))
2273 endfunction
2274
2275 //===========================================================================
2276 function GetSoundDurationBJ takes sound soundHandle returns real
2277 if (soundHandle == null) then
2278 return bj_NOTHING_SOUND_DURATION
2279 else
2280 return I2R(GetSoundDuration(soundHandle)) * 0.001
2281 endif
2282 endfunction
2283
2284 //===========================================================================
2285 function GetSoundFileDurationBJ takes string musicFileName returns real
2286 return I2R(GetSoundFileDuration(musicFileName)) * 0.001
2287 endfunction
2288
2289 //===========================================================================
2290 function GetLastPlayedSound takes nothing returns sound
2291 return bj_lastPlayedSound
2292 endfunction
2293
2294 //===========================================================================
2295 function GetLastPlayedMusic takes nothing returns string
2296 return bj_lastPlayedMusic
2297 endfunction
2298
2299 //===========================================================================
2300 function VolumeGroupSetVolumeBJ takes volumegroup vgroup, real percent returns nothing
2301 call VolumeGroupSetVolume(vgroup, percent * 0.01)
2302 endfunction
2303
2304 //===========================================================================
2305 function SetCineModeVolumeGroupsImmediateBJ takes nothing returns nothing
2306 call VolumeGroupSetVolume(SOUND_VOLUMEGROUP_UNITMOVEMENT, bj_CINEMODE_VOLUME_UNITMOVEMENT)
2307 call VolumeGroupSetVolume(SOUND_VOLUMEGROUP_UNITSOUNDS, bj_CINEMODE_VOLUME_UNITSOUNDS)
2308 call VolumeGroupSetVolume(SOUND_VOLUMEGROUP_COMBAT, bj_CINEMODE_VOLUME_COMBAT)
2309 call VolumeGroupSetVolume(SOUND_VOLUMEGROUP_SPELLS, bj_CINEMODE_VOLUME_SPELLS)
2310 call VolumeGroupSetVolume(SOUND_VOLUMEGROUP_UI, bj_CINEMODE_VOLUME_UI)
2311 call VolumeGroupSetVolume(SOUND_VOLUMEGROUP_MUSIC, bj_CINEMODE_VOLUME_MUSIC)
2312 call VolumeGroupSetVolume(SOUND_VOLUMEGROUP_AMBIENTSOUNDS, bj_CINEMODE_VOLUME_AMBIENTSOUNDS)
2313 call VolumeGroupSetVolume(SOUND_VOLUMEGROUP_FIRE, bj_CINEMODE_VOLUME_FIRE)
2314 endfunction
2315
2316 //===========================================================================
2317 function SetCineModeVolumeGroupsBJ takes nothing returns nothing
2318 // Delay the request if it occurs at map init.
2319 if bj_gameStarted then
2320 call SetCineModeVolumeGroupsImmediateBJ()
2321 else
2322 call TimerStart(bj_volumeGroupsTimer, bj_GAME_STARTED_THRESHOLD, false, function SetCineModeVolumeGroupsImmediateBJ)
2323 endif
2324 endfunction
2325
2326 //===========================================================================
2327 function SetSpeechVolumeGroupsImmediateBJ takes nothing returns nothing
2328 call VolumeGroupSetVolume(SOUND_VOLUMEGROUP_UNITMOVEMENT, bj_SPEECH_VOLUME_UNITMOVEMENT)
2329 call VolumeGroupSetVolume(SOUND_VOLUMEGROUP_UNITSOUNDS, bj_SPEECH_VOLUME_UNITSOUNDS)
2330 call VolumeGroupSetVolume(SOUND_VOLUMEGROUP_COMBAT, bj_SPEECH_VOLUME_COMBAT)
2331 call VolumeGroupSetVolume(SOUND_VOLUMEGROUP_SPELLS, bj_SPEECH_VOLUME_SPELLS)
2332 call VolumeGroupSetVolume(SOUND_VOLUMEGROUP_UI, bj_SPEECH_VOLUME_UI)
2333 call VolumeGroupSetVolume(SOUND_VOLUMEGROUP_MUSIC, bj_SPEECH_VOLUME_MUSIC)
2334 call VolumeGroupSetVolume(SOUND_VOLUMEGROUP_AMBIENTSOUNDS, bj_SPEECH_VOLUME_AMBIENTSOUNDS)
2335 call VolumeGroupSetVolume(SOUND_VOLUMEGROUP_FIRE, bj_SPEECH_VOLUME_FIRE)
2336 endfunction
2337
2338 //===========================================================================
2339 function SetSpeechVolumeGroupsBJ takes nothing returns nothing
2340 // Delay the request if it occurs at map init.
2341 if bj_gameStarted then
2342 call SetSpeechVolumeGroupsImmediateBJ()
2343 else
2344 call TimerStart(bj_volumeGroupsTimer, bj_GAME_STARTED_THRESHOLD, false, function SetSpeechVolumeGroupsImmediateBJ)
2345 endif
2346 endfunction
2347
2348 //===========================================================================
2349 function VolumeGroupResetImmediateBJ takes nothing returns nothing
2350 call VolumeGroupReset()
2351 endfunction
2352
2353 //===========================================================================
2354 function VolumeGroupResetBJ takes nothing returns nothing
2355 // Delay the request if it occurs at map init.
2356 if bj_gameStarted then
2357 call VolumeGroupResetImmediateBJ()
2358 else
2359 call TimerStart(bj_volumeGroupsTimer, bj_GAME_STARTED_THRESHOLD, false, function VolumeGroupResetImmediateBJ)
2360 endif
2361 endfunction
2362
2363 //===========================================================================
2364 function GetSoundIsPlayingBJ takes sound soundHandle returns boolean
2365 return GetSoundIsLoading(soundHandle) or GetSoundIsPlaying(soundHandle)
2366 endfunction
2367
2368 //===========================================================================
2369 function WaitForSoundBJ takes sound soundHandle, real offset returns nothing
2370 call TriggerWaitForSound( soundHandle, offset )
2371 endfunction
2372
2373 //===========================================================================
2374 function SetMapMusicIndexedBJ takes string musicName, integer index returns nothing
2375 call SetMapMusic(musicName, false, index)
2376 endfunction
2377
2378 //===========================================================================
2379 function SetMapMusicRandomBJ takes string musicName returns nothing
2380 call SetMapMusic(musicName, true, 0)
2381 endfunction
2382
2383 //===========================================================================
2384 function ClearMapMusicBJ takes nothing returns nothing
2385 call ClearMapMusic()
2386 endfunction
2387
2388 //===========================================================================
2389 function SetStackedSoundBJ takes boolean add, sound soundHandle, rect r returns nothing
2390 local real width = GetRectMaxX(r) - GetRectMinX(r)
2391 local real height = GetRectMaxY(r) - GetRectMinY(r)
2392
2393 call SetSoundPosition(soundHandle, GetRectCenterX(r), GetRectCenterY(r), 0)
2394 if add then
2395 call RegisterStackedSound(soundHandle, true, width, height)
2396 else
2397 call UnregisterStackedSound(soundHandle, true, width, height)
2398 endif
2399 endfunction
2400
2401 //===========================================================================
2402 function StartSoundForPlayerBJ takes player whichPlayer, sound soundHandle returns nothing
2403 if (whichPlayer == GetLocalPlayer()) then
2404 call StartSound(soundHandle)
2405 endif
2406 endfunction
2407
2408 //===========================================================================
2409 function VolumeGroupSetVolumeForPlayerBJ takes player whichPlayer, volumegroup vgroup, real scale returns nothing
2410 if (GetLocalPlayer() == whichPlayer) then
2411 call VolumeGroupSetVolume(vgroup, scale)
2412 endif
2413 endfunction
2414
2415 //===========================================================================
2416 function EnableDawnDusk takes boolean flag returns nothing
2417 set bj_useDawnDuskSounds = flag
2418 endfunction
2419
2420 //===========================================================================
2421 function IsDawnDuskEnabled takes nothing returns boolean
2422 return bj_useDawnDuskSounds
2423 endfunction
2424
2425
2426
2427 //***************************************************************************
2428 //*
2429 //* Day/Night ambient sounds
2430 //*
2431 //***************************************************************************
2432
2433 //===========================================================================
2434 function SetAmbientDaySound takes string inLabel returns nothing
2435 local real ToD
2436
2437 // Stop old sound, if necessary
2438 if (bj_dayAmbientSound != null) then
2439 call StopSound(bj_dayAmbientSound, true, true)
2440 endif
2441
2442 // Create new sound
2443 set bj_dayAmbientSound = CreateMIDISound(inLabel, 20, 20)
2444
2445 // Start the sound if necessary, based on current time
2446 set ToD = GetTimeOfDay()
2447 if (ToD >= bj_TOD_DAWN and ToD < bj_TOD_DUSK) then
2448 call StartSound(bj_dayAmbientSound)
2449 endif
2450 endfunction
2451
2452 //===========================================================================
2453 function SetAmbientNightSound takes string inLabel returns nothing
2454 local real ToD
2455
2456 // Stop old sound, if necessary
2457 if (bj_nightAmbientSound != null) then
2458 call StopSound(bj_nightAmbientSound, true, true)
2459 endif
2460
2461 // Create new sound
2462 set bj_nightAmbientSound = CreateMIDISound(inLabel, 20, 20)
2463
2464 // Start the sound if necessary, based on current time
2465 set ToD = GetTimeOfDay()
2466 if (ToD < bj_TOD_DAWN or ToD >= bj_TOD_DUSK) then
2467 call StartSound(bj_nightAmbientSound)
2468 endif
2469 endfunction
2470
2471
2472
2473 //***************************************************************************
2474 //*
2475 //* Special Effect Utility Functions
2476 //*
2477 //***************************************************************************
2478
2479 //===========================================================================
2480 function AddSpecialEffectLocBJ takes location where, string modelName returns effect
2481 set bj_lastCreatedEffect = AddSpecialEffectLoc(modelName, where)
2482 return bj_lastCreatedEffect
2483 endfunction
2484
2485 //===========================================================================
2486 function AddSpecialEffectTargetUnitBJ takes string attachPointName, widget targetWidget, string modelName returns effect
2487 set bj_lastCreatedEffect = AddSpecialEffectTarget(modelName, targetWidget, attachPointName)
2488 return bj_lastCreatedEffect
2489 endfunction
2490
2491 //===========================================================================
2492 // Two distinct trigger actions can't share the same function name, so this
2493 // dummy function simply mimics the behavior of an existing call.
2494 //
2495 // Commented out - Destructibles have no attachment points.
2496 //
2497 //function AddSpecialEffectTargetDestructableBJ takes string attachPointName, widget targetWidget, string modelName returns effect
2498 // return AddSpecialEffectTargetUnitBJ(attachPointName, targetWidget, modelName)
2499 //endfunction
2500
2501 //===========================================================================
2502 // Two distinct trigger actions can't share the same function name, so this
2503 // dummy function simply mimics the behavior of an existing call.
2504 //
2505 // Commented out - Items have no attachment points.
2506 //
2507 //function AddSpecialEffectTargetItemBJ takes string attachPointName, widget targetWidget, string modelName returns effect
2508 // return AddSpecialEffectTargetUnitBJ(attachPointName, targetWidget, modelName)
2509 //endfunction
2510
2511 //===========================================================================
2512 function DestroyEffectBJ takes effect whichEffect returns nothing
2513 call DestroyEffect(whichEffect)
2514 endfunction
2515
2516 //===========================================================================
2517 function GetLastCreatedEffectBJ takes nothing returns effect
2518 return bj_lastCreatedEffect
2519 endfunction
2520
2521
2522
2523 //***************************************************************************
2524 //*
2525 //* Hero and Item Utility Functions
2526 //*
2527 //***************************************************************************
2528
2529 //===========================================================================
2530 function GetItemLoc takes item whichItem returns location
2531 return Location(GetItemX(whichItem), GetItemY(whichItem))
2532 endfunction
2533
2534 //===========================================================================
2535 function GetItemLifeBJ takes widget whichWidget returns real
2536 return GetWidgetLife(whichWidget)
2537 endfunction
2538
2539 //===========================================================================
2540 function SetItemLifeBJ takes widget whichWidget, real life returns nothing
2541 call SetWidgetLife(whichWidget, life)
2542 endfunction
2543
2544 //===========================================================================
2545 function AddHeroXPSwapped takes integer xpToAdd, unit whichHero, boolean showEyeCandy returns nothing
2546 call AddHeroXP(whichHero, xpToAdd, showEyeCandy)
2547 endfunction
2548
2549 //===========================================================================
2550 function SetHeroLevelBJ takes unit whichHero, integer newLevel, boolean showEyeCandy returns nothing
2551 local integer oldLevel = GetHeroLevel(whichHero)
2552
2553 if (newLevel > oldLevel) then
2554 call SetHeroLevel(whichHero, newLevel, showEyeCandy)
2555 elseif (newLevel < oldLevel) then
2556 call UnitStripHeroLevel(whichHero, oldLevel - newLevel)
2557 else
2558 // No change in level - ignore the request.
2559 endif
2560 endfunction
2561
2562 //===========================================================================
2563 function DecUnitAbilityLevelSwapped takes integer abilcode, unit whichUnit returns integer
2564 return DecUnitAbilityLevel(whichUnit, abilcode)
2565 endfunction
2566
2567 //===========================================================================
2568 function IncUnitAbilityLevelSwapped takes integer abilcode, unit whichUnit returns integer
2569 return IncUnitAbilityLevel(whichUnit, abilcode)
2570 endfunction
2571
2572 //===========================================================================
2573 function SetUnitAbilityLevelSwapped takes integer abilcode, unit whichUnit, integer level returns integer
2574 return SetUnitAbilityLevel(whichUnit, abilcode, level)
2575 endfunction
2576
2577 //===========================================================================
2578 function GetUnitAbilityLevelSwapped takes integer abilcode, unit whichUnit returns integer
2579 return GetUnitAbilityLevel(whichUnit, abilcode)
2580 endfunction
2581
2582 //===========================================================================
2583 function UnitHasBuffBJ takes unit whichUnit, integer buffcode returns boolean
2584 return (GetUnitAbilityLevel(whichUnit, buffcode) > 0)
2585 endfunction
2586
2587 //===========================================================================
2588 function UnitRemoveBuffBJ takes integer buffcode, unit whichUnit returns boolean
2589 return UnitRemoveAbility(whichUnit, buffcode)
2590 endfunction
2591
2592 //===========================================================================
2593 function UnitAddItemSwapped takes item whichItem, unit whichHero returns boolean
2594 return UnitAddItem(whichHero, whichItem)
2595 endfunction
2596
2597 //===========================================================================
2598 function UnitAddItemByIdSwapped takes integer itemId, unit whichHero returns item
2599 // Create the item at the hero's feet first, and then give it to him.
2600 // This is to ensure that the item will be left at the hero's feet if
2601 // his inventory is full.
2602 set bj_lastCreatedItem = CreateItem(itemId, GetUnitX(whichHero), GetUnitY(whichHero))
2603 call UnitAddItem(whichHero, bj_lastCreatedItem)
2604 return bj_lastCreatedItem
2605 endfunction
2606
2607 //===========================================================================
2608 function UnitRemoveItemSwapped takes item whichItem, unit whichHero returns nothing
2609 set bj_lastRemovedItem = whichItem
2610 call UnitRemoveItem(whichHero, whichItem)
2611 endfunction
2612
2613 //===========================================================================
2614 // Translates 0-based slot indices to 1-based slot indices.
2615 //
2616 function UnitRemoveItemFromSlotSwapped takes integer itemSlot, unit whichHero returns item
2617 set bj_lastRemovedItem = UnitRemoveItemFromSlot(whichHero, itemSlot-1)
2618 return bj_lastRemovedItem
2619 endfunction
2620
2621 //===========================================================================
2622 function CreateItemLoc takes integer itemId, location loc returns item
2623 set bj_lastCreatedItem = CreateItem(itemId, GetLocationX(loc), GetLocationY(loc))
2624 return bj_lastCreatedItem
2625 endfunction
2626
2627 //===========================================================================
2628 function GetLastCreatedItem takes nothing returns item
2629 return bj_lastCreatedItem
2630 endfunction
2631
2632 //===========================================================================
2633 function GetLastRemovedItem takes nothing returns item
2634 return bj_lastRemovedItem
2635 endfunction
2636
2637 //===========================================================================
2638 function SetItemPositionLoc takes item whichItem, location loc returns nothing
2639 call SetItemPosition(whichItem, GetLocationX(loc), GetLocationY(loc))
2640 endfunction
2641
2642 //===========================================================================
2643 function GetLearnedSkillBJ takes nothing returns integer
2644 return GetLearnedSkill()
2645 endfunction
2646
2647 //===========================================================================
2648 function SuspendHeroXPBJ takes boolean flag, unit whichHero returns nothing
2649 call SuspendHeroXP(whichHero, not flag)
2650 endfunction
2651
2652 //===========================================================================
2653 function SetPlayerHandicapXPBJ takes player whichPlayer, real handicapPercent returns nothing
2654 call SetPlayerHandicapXP(whichPlayer, handicapPercent * 0.01)
2655 endfunction
2656
2657 //===========================================================================
2658 function GetPlayerHandicapXPBJ takes player whichPlayer returns real
2659 return GetPlayerHandicapXP(whichPlayer) * 100
2660 endfunction
2661
2662 //===========================================================================
2663 function SetPlayerHandicapBJ takes player whichPlayer, real handicapPercent returns nothing
2664 call SetPlayerHandicap(whichPlayer, handicapPercent * 0.01)
2665 endfunction
2666
2667 //===========================================================================
2668 function GetPlayerHandicapBJ takes player whichPlayer returns real
2669 return GetPlayerHandicap(whichPlayer) * 100
2670 endfunction
2671
2672 //===========================================================================
2673 function GetHeroStatBJ takes integer whichStat, unit whichHero, boolean includeBonuses returns integer
2674 if (whichStat == bj_HEROSTAT_STR) then
2675 return GetHeroStr(whichHero, includeBonuses)
2676 elseif (whichStat == bj_HEROSTAT_AGI) then
2677 return GetHeroAgi(whichHero, includeBonuses)
2678 elseif (whichStat == bj_HEROSTAT_INT) then
2679 return GetHeroInt(whichHero, includeBonuses)
2680 else
2681 // Unrecognized hero stat - return 0
2682 return 0
2683 endif
2684 endfunction
2685
2686 //===========================================================================
2687 function SetHeroStat takes unit whichHero, integer whichStat, integer value returns nothing
2688 // Ignore requests for negative hero stats.
2689 if (value <= 0) then
2690 return
2691 endif
2692
2693 if (whichStat == bj_HEROSTAT_STR) then
2694 call SetHeroStr(whichHero, value, true)
2695 elseif (whichStat == bj_HEROSTAT_AGI) then
2696 call SetHeroAgi(whichHero, value, true)
2697 elseif (whichStat == bj_HEROSTAT_INT) then
2698 call SetHeroInt(whichHero, value, true)
2699 else
2700 // Unrecognized hero stat - ignore the request.
2701 endif
2702 endfunction
2703
2704 //===========================================================================
2705 function ModifyHeroStat takes integer whichStat, unit whichHero, integer modifyMethod, integer value returns nothing
2706 if (modifyMethod == bj_MODIFYMETHOD_ADD) then
2707 call SetHeroStat(whichHero, whichStat, GetHeroStatBJ(whichStat, whichHero, false) + value)
2708 elseif (modifyMethod == bj_MODIFYMETHOD_SUB) then
2709 call SetHeroStat(whichHero, whichStat, GetHeroStatBJ(whichStat, whichHero, false) - value)
2710 elseif (modifyMethod == bj_MODIFYMETHOD_SET) then
2711 call SetHeroStat(whichHero, whichStat, value)
2712 else
2713 // Unrecognized modification method - ignore the request.
2714 endif
2715 endfunction
2716
2717 //===========================================================================
2718 function ModifyHeroSkillPoints takes unit whichHero, integer modifyMethod, integer value returns boolean
2719 if (modifyMethod == bj_MODIFYMETHOD_ADD) then
2720 return UnitModifySkillPoints(whichHero, value)
2721 elseif (modifyMethod == bj_MODIFYMETHOD_SUB) then
2722 return UnitModifySkillPoints(whichHero, -value)
2723 elseif (modifyMethod == bj_MODIFYMETHOD_SET) then
2724 return UnitModifySkillPoints(whichHero, value - GetHeroSkillPoints(whichHero))
2725 else
2726 // Unrecognized modification method - ignore the request and return failure.
2727 return false
2728 endif
2729 endfunction
2730
2731 //===========================================================================
2732 function UnitDropItemPointBJ takes unit whichUnit, item whichItem, real x, real y returns boolean
2733 return UnitDropItemPoint(whichUnit, whichItem, x, y)
2734 endfunction
2735
2736 //===========================================================================
2737 function UnitDropItemPointLoc takes unit whichUnit, item whichItem, location loc returns boolean
2738 return UnitDropItemPoint(whichUnit, whichItem, GetLocationX(loc), GetLocationY(loc))
2739 endfunction
2740
2741 //===========================================================================
2742 function UnitDropItemSlotBJ takes unit whichUnit, item whichItem, integer slot returns boolean
2743 return UnitDropItemSlot(whichUnit, whichItem, slot-1)
2744 endfunction
2745
2746 //===========================================================================
2747 function UnitDropItemTargetBJ takes unit whichUnit, item whichItem, widget target returns boolean
2748 return UnitDropItemTarget(whichUnit, whichItem, target)
2749 endfunction
2750
2751 //===========================================================================
2752 // Two distinct trigger actions can't share the same function name, so this
2753 // dummy function simply mimics the behavior of an existing call.
2754 //
2755 function UnitUseItemDestructable takes unit whichUnit, item whichItem, widget target returns boolean
2756 return UnitUseItemTarget(whichUnit, whichItem, target)
2757 endfunction
2758
2759 //===========================================================================
2760 function UnitUseItemPointLoc takes unit whichUnit, item whichItem, location loc returns boolean
2761 return UnitUseItemPoint(whichUnit, whichItem, GetLocationX(loc), GetLocationY(loc))
2762 endfunction
2763
2764 //===========================================================================
2765 // Translates 0-based slot indices to 1-based slot indices.
2766 //
2767 function UnitItemInSlotBJ takes unit whichUnit, integer itemSlot returns item
2768 return UnitItemInSlot(whichUnit, itemSlot-1)
2769 endfunction
2770
2771 //===========================================================================
2772 // Translates 0-based slot indices to 1-based slot indices.
2773 //
2774 function GetInventoryIndexOfItemTypeBJ takes unit whichUnit, integer itemId returns integer
2775 local integer index
2776 local item indexItem
2777
2778 set index = 0
2779 loop
2780 set indexItem = UnitItemInSlot(whichUnit, index)
2781 if (indexItem != null) and (GetItemTypeId(indexItem) == itemId) then
2782 return index + 1
2783 endif
2784
2785 set index = index + 1
2786 exitwhen index >= bj_MAX_INVENTORY
2787 endloop
2788 return 0
2789 endfunction
2790
2791 //===========================================================================
2792 function GetItemOfTypeFromUnitBJ takes unit whichUnit, integer itemId returns item
2793 local integer index = GetInventoryIndexOfItemTypeBJ(whichUnit, itemId)
2794
2795 if (index == 0) then
2796 return null
2797 else
2798 return UnitItemInSlot(whichUnit, index - 1)
2799 endif
2800 endfunction
2801
2802 //===========================================================================
2803 function UnitHasItemOfTypeBJ takes unit whichUnit, integer itemId returns boolean
2804 return GetInventoryIndexOfItemTypeBJ(whichUnit, itemId) > 0
2805 endfunction
2806
2807 //===========================================================================
2808 function UnitInventoryCount takes unit whichUnit returns integer
2809 local integer index = 0
2810 local integer count = 0
2811
2812 loop
2813 if (UnitItemInSlot(whichUnit, index) != null) then
2814 set count = count + 1
2815 endif
2816
2817 set index = index + 1
2818 exitwhen index >= bj_MAX_INVENTORY
2819 endloop
2820
2821 return count
2822 endfunction
2823
2824 //===========================================================================
2825 function UnitInventorySizeBJ takes unit whichUnit returns integer
2826 return UnitInventorySize(whichUnit)
2827 endfunction
2828
2829 //===========================================================================
2830 function SetItemInvulnerableBJ takes item whichItem, boolean flag returns nothing
2831 call SetItemInvulnerable(whichItem, flag)
2832 endfunction
2833
2834 //===========================================================================
2835 function SetItemDropOnDeathBJ takes item whichItem, boolean flag returns nothing
2836 call SetItemDropOnDeath(whichItem, flag)
2837 endfunction
2838
2839 //===========================================================================
2840 function SetItemDroppableBJ takes item whichItem, boolean flag returns nothing
2841 call SetItemDroppable(whichItem, flag)
2842 endfunction
2843
2844 //===========================================================================
2845 function SetItemPlayerBJ takes item whichItem, player whichPlayer, boolean changeColor returns nothing
2846 call SetItemPlayer(whichItem, whichPlayer, changeColor)
2847 endfunction
2848
2849 //===========================================================================
2850 function SetItemVisibleBJ takes boolean show, item whichItem returns nothing
2851 call SetItemVisible(whichItem, show)
2852 endfunction
2853
2854 //===========================================================================
2855 function IsItemHiddenBJ takes item whichItem returns boolean
2856 return not IsItemVisible(whichItem)
2857 endfunction
2858
2859 //===========================================================================
2860 function ChooseRandomItemBJ takes integer level returns integer
2861 return ChooseRandomItem(level)
2862 endfunction
2863
2864 //===========================================================================
2865 function ChooseRandomItemExBJ takes integer level, itemtype whichType returns integer
2866 return ChooseRandomItemEx(whichType, level)
2867 endfunction
2868
2869 //===========================================================================
2870 function ChooseRandomNPBuildingBJ takes nothing returns integer
2871 return ChooseRandomNPBuilding()
2872 endfunction
2873
2874 //===========================================================================
2875 function ChooseRandomCreepBJ takes integer level returns integer
2876 return ChooseRandomCreep(level)
2877 endfunction
2878
2879 //===========================================================================
2880 function EnumItemsInRectBJ takes rect r, code actionFunc returns nothing
2881 call EnumItemsInRect(r, null, actionFunc)
2882 endfunction
2883
2884 //===========================================================================
2885 // See GroupPickRandomUnitEnum for the details of this algorithm.
2886 //
2887 function RandomItemInRectBJEnum takes nothing returns nothing
2888 set bj_itemRandomConsidered = bj_itemRandomConsidered + 1
2889 if (GetRandomInt(1, bj_itemRandomConsidered) == 1) then
2890 set bj_itemRandomCurrentPick = GetEnumItem()
2891 endif
2892 endfunction
2893
2894 //===========================================================================
2895 // Picks a random item from within a rect, matching a condition
2896 //
2897 function RandomItemInRectBJ takes rect r, boolexpr filter returns item
2898 set bj_itemRandomConsidered = 0
2899 set bj_itemRandomCurrentPick = null
2900 call EnumItemsInRect(r, filter, function RandomItemInRectBJEnum)
2901 call DestroyBoolExpr(filter)
2902 return bj_itemRandomCurrentPick
2903 endfunction
2904
2905 //===========================================================================
2906 // Picks a random item from within a rect
2907 //
2908 function RandomItemInRectSimpleBJ takes rect r returns item
2909 return RandomItemInRectBJ(r, null)
2910 endfunction
2911
2912 //===========================================================================
2913 function CheckItemStatus takes item whichItem, integer status returns boolean
2914 if (status == bj_ITEM_STATUS_HIDDEN) then
2915 return not IsItemVisible(whichItem)
2916 elseif (status == bj_ITEM_STATUS_OWNED) then
2917 return IsItemOwned(whichItem)
2918 elseif (status == bj_ITEM_STATUS_INVULNERABLE) then
2919 return IsItemInvulnerable(whichItem)
2920 elseif (status == bj_ITEM_STATUS_POWERUP) then
2921 return IsItemPowerup(whichItem)
2922 elseif (status == bj_ITEM_STATUS_SELLABLE) then
2923 return IsItemSellable(whichItem)
2924 elseif (status == bj_ITEM_STATUS_PAWNABLE) then
2925 return IsItemPawnable(whichItem)
2926 else
2927 // Unrecognized status - return false
2928 return false
2929 endif
2930 endfunction
2931
2932 //===========================================================================
2933 function CheckItemcodeStatus takes integer itemId, integer status returns boolean
2934 if (status == bj_ITEMCODE_STATUS_POWERUP) then
2935 return IsItemIdPowerup(itemId)
2936 elseif (status == bj_ITEMCODE_STATUS_SELLABLE) then
2937 return IsItemIdSellable(itemId)
2938 elseif (status == bj_ITEMCODE_STATUS_PAWNABLE) then
2939 return IsItemIdPawnable(itemId)
2940 else
2941 // Unrecognized status - return false
2942 return false
2943 endif
2944 endfunction
2945
2946
2947
2948 //***************************************************************************
2949 //*
2950 //* Unit Utility Functions
2951 //*
2952 //***************************************************************************
2953
2954 //===========================================================================
2955 function UnitId2OrderIdBJ takes integer unitId returns integer
2956 return unitId
2957 endfunction
2958
2959 //===========================================================================
2960 function String2UnitIdBJ takes string unitIdString returns integer
2961 return UnitId(unitIdString)
2962 endfunction
2963
2964 //===========================================================================
2965 function UnitId2StringBJ takes integer unitId returns string
2966 local string unitString = UnitId2String(unitId)
2967
2968 if (unitString != null) then
2969 return unitString
2970 endif
2971
2972 // The unitId was not recognized - return an empty string.
2973 return ""
2974 endfunction
2975
2976 //===========================================================================
2977 function String2OrderIdBJ takes string orderIdString returns integer
2978 local integer orderId
2979
2980 // Check to see if it's a generic order.
2981 set orderId = OrderId(orderIdString)
2982 if (orderId != 0) then
2983 return orderId
2984 endif
2985
2986 // Check to see if it's a (train) unit order.
2987 set orderId = UnitId(orderIdString)
2988 if (orderId != 0) then
2989 return orderId
2990 endif
2991
2992 // Unrecognized - return 0
2993 return 0
2994 endfunction
2995
2996 //===========================================================================
2997 function OrderId2StringBJ takes integer orderId returns string
2998 local string orderString
2999
3000 // Check to see if it's a generic order.
3001 set orderString = OrderId2String(orderId)
3002 if (orderString != null) then
3003 return orderString
3004 endif
3005
3006 // Check to see if it's a (train) unit order.
3007 set orderString = UnitId2String(orderId)
3008 if (orderString != null) then
3009 return orderString
3010 endif
3011
3012 // Unrecognized - return an empty string.
3013 return ""
3014 endfunction
3015
3016 //===========================================================================
3017 function GetIssuedOrderIdBJ takes nothing returns integer
3018 return GetIssuedOrderId()
3019 endfunction
3020
3021 //===========================================================================
3022 function GetKillingUnitBJ takes nothing returns unit
3023 return GetKillingUnit()
3024 endfunction
3025
3026 //===========================================================================
3027 function CreateUnitAtLocSaveLast takes player id, integer unitid, location loc, real face returns unit
3028 if (unitid == 'ugol') then
3029 set bj_lastCreatedUnit = CreateBlightedGoldmine(id, GetLocationX(loc), GetLocationY(loc), face)
3030 else
3031 set bj_lastCreatedUnit = CreateUnitAtLoc(id, unitid, loc, face)
3032 endif
3033
3034 return bj_lastCreatedUnit
3035 endfunction
3036
3037 //===========================================================================
3038 function GetLastCreatedUnit takes nothing returns unit
3039 return bj_lastCreatedUnit
3040 endfunction
3041
3042 //===========================================================================
3043 function CreateNUnitsAtLoc takes integer count, integer unitId, player whichPlayer, location loc, real face returns group
3044 call GroupClear(bj_lastCreatedGroup)
3045 loop
3046 set count = count - 1
3047 exitwhen count < 0
3048 call CreateUnitAtLocSaveLast(whichPlayer, unitId, loc, face)
3049 call GroupAddUnit(bj_lastCreatedGroup, bj_lastCreatedUnit)
3050 endloop
3051 return bj_lastCreatedGroup
3052 endfunction
3053
3054 //===========================================================================
3055 function CreateNUnitsAtLocFacingLocBJ takes integer count, integer unitId, player whichPlayer, location loc, location lookAt returns group
3056 return CreateNUnitsAtLoc(count, unitId, whichPlayer, loc, AngleBetweenPoints(loc, lookAt))
3057 endfunction
3058
3059 //===========================================================================
3060 function GetLastCreatedGroupEnum takes nothing returns nothing
3061 call GroupAddUnit(bj_groupLastCreatedDest, GetEnumUnit())
3062 endfunction
3063
3064 //===========================================================================
3065 function GetLastCreatedGroup takes nothing returns group
3066 set bj_groupLastCreatedDest = CreateGroup()
3067 call ForGroup(bj_lastCreatedGroup, function GetLastCreatedGroupEnum)
3068 return bj_groupLastCreatedDest
3069 endfunction
3070
3071 //===========================================================================
3072 function CreateCorpseLocBJ takes integer unitid, player whichPlayer, location loc returns unit
3073 set bj_lastCreatedUnit = CreateCorpse(whichPlayer, unitid, GetLocationX(loc), GetLocationY(loc), GetRandomReal(0, 360))
3074 return bj_lastCreatedUnit
3075 endfunction
3076
3077 //===========================================================================
3078 function UnitSuspendDecayBJ takes boolean suspend, unit whichUnit returns nothing
3079 call UnitSuspendDecay(whichUnit, suspend)
3080 endfunction
3081
3082 //===========================================================================
3083 function DelayedSuspendDecayStopAnimEnum takes nothing returns nothing
3084 local unit enumUnit = GetEnumUnit()
3085
3086 if (GetUnitState(enumUnit, UNIT_STATE_LIFE) <= 0) then
3087 call SetUnitTimeScale(enumUnit, 0.0001)
3088 endif
3089 endfunction
3090
3091 //===========================================================================
3092 function DelayedSuspendDecayBoneEnum takes nothing returns nothing
3093 local unit enumUnit = GetEnumUnit()
3094
3095 if (GetUnitState(enumUnit, UNIT_STATE_LIFE) <= 0) then
3096 call UnitSuspendDecay(enumUnit, true)
3097 call SetUnitTimeScale(enumUnit, 0.0001)
3098 endif
3099 endfunction
3100
3101 //===========================================================================
3102 // Game code explicitly sets the animation back to "decay bone" after the
3103 // initial corpse fades away, so we reset it now. It's best not to show
3104 // off corpses thus created until after this grace period has passed.
3105 //
3106 function DelayedSuspendDecayFleshEnum takes nothing returns nothing
3107 local unit enumUnit = GetEnumUnit()
3108
3109 if (GetUnitState(enumUnit, UNIT_STATE_LIFE) <= 0) then
3110 call UnitSuspendDecay(enumUnit, true)
3111 call SetUnitTimeScale(enumUnit, 10.0)
3112 call SetUnitAnimation(enumUnit, "decay flesh")
3113 endif
3114 endfunction
3115
3116 //===========================================================================
3117 // Waits a short period of time to ensure that the corpse is decaying, and
3118 // then suspend the animation and corpse decay.
3119 //
3120 function DelayedSuspendDecay takes nothing returns nothing
3121 local group boneGroup
3122 local group fleshGroup
3123
3124 // Switch the global unit groups over to local variables and recreate
3125 // the global versions, so that this function can handle overlapping
3126 // calls.
3127 set boneGroup = bj_suspendDecayBoneGroup
3128 set fleshGroup = bj_suspendDecayFleshGroup
3129 set bj_suspendDecayBoneGroup = CreateGroup()
3130 set bj_suspendDecayFleshGroup = CreateGroup()
3131
3132 call ForGroup(fleshGroup, function DelayedSuspendDecayStopAnimEnum)
3133 call ForGroup(boneGroup, function DelayedSuspendDecayStopAnimEnum)
3134
3135 call TriggerSleepAction(bj_CORPSE_MAX_DEATH_TIME)
3136 call ForGroup(fleshGroup, function DelayedSuspendDecayFleshEnum)
3137 call ForGroup(boneGroup, function DelayedSuspendDecayBoneEnum)
3138
3139 call TriggerSleepAction(0.05)
3140 call ForGroup(fleshGroup, function DelayedSuspendDecayStopAnimEnum)
3141
3142 call DestroyGroup(boneGroup)
3143 call DestroyGroup(fleshGroup)
3144 endfunction
3145
3146 //===========================================================================
3147 function DelayedSuspendDecayCreate takes nothing returns nothing
3148 set bj_delayedSuspendDecayTrig = CreateTrigger()
3149 call TriggerRegisterTimerExpireEvent(bj_delayedSuspendDecayTrig, bj_delayedSuspendDecayTimer)
3150 call TriggerAddAction(bj_delayedSuspendDecayTrig, function DelayedSuspendDecay)
3151 endfunction
3152
3153 //===========================================================================
3154 function CreatePermanentCorpseLocBJ takes integer style, integer unitid, player whichPlayer, location loc, real facing returns unit
3155 set bj_lastCreatedUnit = CreateCorpse(whichPlayer, unitid, GetLocationX(loc), GetLocationY(loc), facing)
3156 call SetUnitBlendTime(bj_lastCreatedUnit, 0)
3157
3158 if (style == bj_CORPSETYPE_FLESH) then
3159 call SetUnitAnimation(bj_lastCreatedUnit, "decay flesh")
3160 call GroupAddUnit(bj_suspendDecayFleshGroup, bj_lastCreatedUnit)
3161 elseif (style == bj_CORPSETYPE_BONE) then
3162 call SetUnitAnimation(bj_lastCreatedUnit, "decay bone")
3163 call GroupAddUnit(bj_suspendDecayBoneGroup, bj_lastCreatedUnit)
3164 else
3165 // Unknown decay style - treat as skeletal.
3166 call SetUnitAnimation(bj_lastCreatedUnit, "decay bone")
3167 call GroupAddUnit(bj_suspendDecayBoneGroup, bj_lastCreatedUnit)
3168 endif
3169
3170 call TimerStart(bj_delayedSuspendDecayTimer, 0.05, false, null)
3171 return bj_lastCreatedUnit
3172 endfunction
3173
3174 //===========================================================================
3175 function GetUnitStateSwap takes unitstate whichState, unit whichUnit returns real
3176 return GetUnitState(whichUnit, whichState)
3177 endfunction
3178
3179 //===========================================================================
3180 function GetUnitStatePercent takes unit whichUnit, unitstate whichState, unitstate whichMaxState returns real
3181 local real value = GetUnitState(whichUnit, whichState)
3182 local real maxValue = GetUnitState(whichUnit, whichMaxState)
3183
3184 // Return 0 for null units.
3185 if (whichUnit == null) or (maxValue == 0) then
3186 return 0.0
3187 endif
3188
3189 return value / maxValue * 100.0
3190 endfunction
3191
3192 //===========================================================================
3193 function GetUnitLifePercent takes unit whichUnit returns real
3194 return GetUnitStatePercent(whichUnit, UNIT_STATE_LIFE, UNIT_STATE_MAX_LIFE)
3195 endfunction
3196
3197 //===========================================================================
3198 function GetUnitManaPercent takes unit whichUnit returns real
3199 return GetUnitStatePercent(whichUnit, UNIT_STATE_MANA, UNIT_STATE_MAX_MANA)
3200 endfunction
3201
3202 //===========================================================================
3203 function SelectUnitSingle takes unit whichUnit returns nothing
3204 call ClearSelection()
3205 call SelectUnit(whichUnit, true)
3206 endfunction
3207
3208 //===========================================================================
3209 function SelectGroupBJEnum takes nothing returns nothing
3210 call SelectUnit( GetEnumUnit(), true )
3211 endfunction
3212
3213 //===========================================================================
3214 function SelectGroupBJ takes group g returns nothing
3215 call ClearSelection()
3216 call ForGroup( g, function SelectGroupBJEnum )
3217 endfunction
3218
3219 //===========================================================================
3220 function SelectUnitAdd takes unit whichUnit returns nothing
3221 call SelectUnit(whichUnit, true)
3222 endfunction
3223
3224 //===========================================================================
3225 function SelectUnitRemove takes unit whichUnit returns nothing
3226 call SelectUnit(whichUnit, false)
3227 endfunction
3228
3229 //===========================================================================
3230 function ClearSelectionForPlayer takes player whichPlayer returns nothing
3231 if (GetLocalPlayer() == whichPlayer) then
3232 // Use only local code (no net traffic) within this block to avoid desyncs.
3233 call ClearSelection()
3234 endif
3235 endfunction
3236
3237 //===========================================================================
3238 function SelectUnitForPlayerSingle takes unit whichUnit, player whichPlayer returns nothing
3239 if (GetLocalPlayer() == whichPlayer) then
3240 // Use only local code (no net traffic) within this block to avoid desyncs.
3241 call ClearSelection()
3242 call SelectUnit(whichUnit, true)
3243 endif
3244 endfunction
3245
3246 //===========================================================================
3247 function SelectGroupForPlayerBJ takes group g, player whichPlayer returns nothing
3248 if (GetLocalPlayer() == whichPlayer) then
3249 // Use only local code (no net traffic) within this block to avoid desyncs.
3250 call ClearSelection()
3251 call ForGroup( g, function SelectGroupBJEnum )
3252 endif
3253 endfunction
3254
3255 //===========================================================================
3256 function SelectUnitAddForPlayer takes unit whichUnit, player whichPlayer returns nothing
3257 if (GetLocalPlayer() == whichPlayer) then
3258 // Use only local code (no net traffic) within this block to avoid desyncs.
3259 call SelectUnit(whichUnit, true)
3260 endif
3261 endfunction
3262
3263 //===========================================================================
3264 function SelectUnitRemoveForPlayer takes unit whichUnit, player whichPlayer returns nothing
3265 if (GetLocalPlayer() == whichPlayer) then
3266 // Use only local code (no net traffic) within this block to avoid desyncs.
3267 call SelectUnit(whichUnit, false)
3268 endif
3269 endfunction
3270
3271 //===========================================================================
3272 function SetUnitLifeBJ takes unit whichUnit, real newValue returns nothing
3273 call SetUnitState(whichUnit, UNIT_STATE_LIFE, RMaxBJ(0,newValue))
3274 endfunction
3275
3276 //===========================================================================
3277 function SetUnitManaBJ takes unit whichUnit, real newValue returns nothing
3278 call SetUnitState(whichUnit, UNIT_STATE_MANA, RMaxBJ(0,newValue))
3279 endfunction
3280
3281 //===========================================================================
3282 function SetUnitLifePercentBJ takes unit whichUnit, real percent returns nothing
3283 call SetUnitState(whichUnit, UNIT_STATE_LIFE, GetUnitState(whichUnit, UNIT_STATE_MAX_LIFE) * RMaxBJ(0,percent) * 0.01)
3284 endfunction
3285
3286 //===========================================================================
3287 function SetUnitManaPercentBJ takes unit whichUnit, real percent returns nothing
3288 call SetUnitState(whichUnit, UNIT_STATE_MANA, GetUnitState(whichUnit, UNIT_STATE_MAX_MANA) * RMaxBJ(0,percent) * 0.01)
3289 endfunction
3290
3291 //===========================================================================
3292 function IsUnitDeadBJ takes unit whichUnit returns boolean
3293 return GetUnitState(whichUnit, UNIT_STATE_LIFE) <= 0
3294 endfunction
3295
3296 //===========================================================================
3297 function IsUnitAliveBJ takes unit whichUnit returns boolean
3298 return not IsUnitDeadBJ(whichUnit)
3299 endfunction
3300
3301 //===========================================================================
3302 function IsUnitGroupDeadBJEnum takes nothing returns nothing
3303 if not IsUnitDeadBJ(GetEnumUnit()) then
3304 set bj_isUnitGroupDeadResult = false
3305 endif
3306 endfunction
3307
3308 //===========================================================================
3309 // Returns true if every unit of the group is dead.
3310 //
3311 function IsUnitGroupDeadBJ takes group g returns boolean
3312 // If the user wants the group destroyed, remember that fact and clear
3313 // the flag, in case it is used again in the callback.
3314 local boolean wantDestroy = bj_wantDestroyGroup
3315 set bj_wantDestroyGroup = false
3316
3317 set bj_isUnitGroupDeadResult = true
3318 call ForGroup(g, function IsUnitGroupDeadBJEnum)
3319
3320 // If the user wants the group destroyed, do so now.
3321 if (wantDestroy) then
3322 call DestroyGroup(g)
3323 endif
3324 return bj_isUnitGroupDeadResult
3325 endfunction
3326
3327 //===========================================================================
3328 function IsUnitGroupEmptyBJEnum takes nothing returns nothing
3329 set bj_isUnitGroupEmptyResult = false
3330 endfunction
3331
3332 //===========================================================================
3333 // Returns true if the group contains no units.
3334 //
3335 function IsUnitGroupEmptyBJ takes group g returns boolean
3336 // If the user wants the group destroyed, remember that fact and clear
3337 // the flag, in case it is used again in the callback.
3338 local boolean wantDestroy = bj_wantDestroyGroup
3339 set bj_wantDestroyGroup = false
3340
3341 set bj_isUnitGroupEmptyResult = true
3342 call ForGroup(g, function IsUnitGroupEmptyBJEnum)
3343
3344 // If the user wants the group destroyed, do so now.
3345 if (wantDestroy) then
3346 call DestroyGroup(g)
3347 endif
3348 return bj_isUnitGroupEmptyResult
3349 endfunction
3350
3351 //===========================================================================
3352 function IsUnitGroupInRectBJEnum takes nothing returns nothing
3353 if not RectContainsUnit(bj_isUnitGroupInRectRect, GetEnumUnit()) then
3354 set bj_isUnitGroupInRectResult = false
3355 endif
3356 endfunction
3357
3358 //===========================================================================
3359 // Returns true if every unit of the group is within the given rect.
3360 //
3361 function IsUnitGroupInRectBJ takes group g, rect r returns boolean
3362 set bj_isUnitGroupInRectResult = true
3363 set bj_isUnitGroupInRectRect = r
3364 call ForGroup(g, function IsUnitGroupInRectBJEnum)
3365 return bj_isUnitGroupInRectResult
3366 endfunction
3367
3368 //===========================================================================
3369 function IsUnitHiddenBJ takes unit whichUnit returns boolean
3370 return IsUnitHidden(whichUnit)
3371 endfunction
3372
3373 //===========================================================================
3374 function ShowUnitHide takes unit whichUnit returns nothing
3375 call ShowUnit(whichUnit, false)
3376 endfunction
3377
3378 //===========================================================================
3379 function ShowUnitShow takes unit whichUnit returns nothing
3380 // Prevent dead heroes from being unhidden.
3381 if (IsUnitType(whichUnit, UNIT_TYPE_HERO) and IsUnitDeadBJ(whichUnit)) then
3382 return
3383 endif
3384
3385 call ShowUnit(whichUnit, true)
3386 endfunction
3387
3388 //===========================================================================
3389 function IssueHauntOrderAtLocBJFilter takes nothing returns boolean
3390 return GetUnitTypeId(GetFilterUnit()) == 'ngol'
3391 endfunction
3392
3393 //===========================================================================
3394 function IssueHauntOrderAtLocBJ takes unit whichPeon, location loc returns boolean
3395 local group g = null
3396 local unit goldMine = null
3397
3398 // Search for a gold mine within a 1-cell radius of the specified location.
3399 set g = CreateGroup()
3400 call GroupEnumUnitsInRangeOfLoc(g, loc, 2*bj_CELLWIDTH, filterIssueHauntOrderAtLocBJ)
3401 set goldMine = FirstOfGroup(g)
3402 call DestroyGroup(g)
3403
3404 // If no mine was found, abort the request.
3405 if (goldMine == null) then
3406 return false
3407 endif
3408
3409 // Issue the Haunt Gold Mine order.
3410 return IssueTargetOrderById(whichPeon, 'ugol', goldMine)
3411 endfunction
3412
3413 //===========================================================================
3414 function IssueBuildOrderByIdLocBJ takes unit whichPeon, integer unitId, location loc returns boolean
3415 if (unitId == 'ugol') then
3416 return IssueHauntOrderAtLocBJ(whichPeon, loc)
3417 else
3418 return IssueBuildOrderById(whichPeon, unitId, GetLocationX(loc), GetLocationY(loc))
3419 endif
3420 endfunction
3421
3422 //===========================================================================
3423 function IssueTrainOrderByIdBJ takes unit whichUnit, integer unitId returns boolean
3424 return IssueImmediateOrderById(whichUnit, unitId)
3425 endfunction
3426
3427 //===========================================================================
3428 function GroupTrainOrderByIdBJ takes group g, integer unitId returns boolean
3429 return GroupImmediateOrderById(g, unitId)
3430 endfunction
3431
3432 //===========================================================================
3433 function IssueUpgradeOrderByIdBJ takes unit whichUnit, integer techId returns boolean
3434 return IssueImmediateOrderById(whichUnit, techId)
3435 endfunction
3436
3437 //===========================================================================
3438 function GetAttackedUnitBJ takes nothing returns unit
3439 return GetTriggerUnit()
3440 endfunction
3441
3442 //===========================================================================
3443 function SetUnitFlyHeightBJ takes unit whichUnit, real newHeight, real rate returns nothing
3444 call SetUnitFlyHeight(whichUnit, newHeight, rate)
3445 endfunction
3446
3447 //===========================================================================
3448 function SetUnitTurnSpeedBJ takes unit whichUnit, real turnSpeed returns nothing
3449 call SetUnitTurnSpeed(whichUnit, turnSpeed)
3450 endfunction
3451
3452 //===========================================================================
3453 function SetUnitPropWindowBJ takes unit whichUnit, real propWindow returns nothing
3454 local real angle = propWindow
3455 if (angle <= 0) then
3456 set angle = 1
3457 elseif (angle >= 360) then
3458 set angle = 359
3459 endif
3460 set angle = angle * bj_DEGTORAD
3461
3462 call SetUnitPropWindow(whichUnit, angle)
3463 endfunction
3464
3465 //===========================================================================
3466 function GetUnitPropWindowBJ takes unit whichUnit returns real
3467 return GetUnitPropWindow(whichUnit) * bj_RADTODEG
3468 endfunction
3469
3470 //===========================================================================
3471 function GetUnitDefaultPropWindowBJ takes unit whichUnit returns real
3472 return GetUnitDefaultPropWindow(whichUnit)
3473 endfunction
3474
3475 //===========================================================================
3476 function SetUnitBlendTimeBJ takes unit whichUnit, real blendTime returns nothing
3477 call SetUnitBlendTime(whichUnit, blendTime)
3478 endfunction
3479
3480 //===========================================================================
3481 function SetUnitAcquireRangeBJ takes unit whichUnit, real acquireRange returns nothing
3482 call SetUnitAcquireRange(whichUnit, acquireRange)
3483 endfunction
3484
3485 //===========================================================================
3486 function UnitSetCanSleepBJ takes unit whichUnit, boolean canSleep returns nothing
3487 call UnitAddSleep(whichUnit, canSleep)
3488 endfunction
3489
3490 //===========================================================================
3491 function UnitCanSleepBJ takes unit whichUnit returns boolean
3492 return UnitCanSleep(whichUnit)
3493 endfunction
3494
3495 //===========================================================================
3496 function UnitWakeUpBJ takes unit whichUnit returns nothing
3497 call UnitWakeUp(whichUnit)
3498 endfunction
3499
3500 //===========================================================================
3501 function UnitIsSleepingBJ takes unit whichUnit returns boolean
3502 return UnitIsSleeping(whichUnit)
3503 endfunction
3504
3505 //===========================================================================
3506 function WakePlayerUnitsEnum takes nothing returns nothing
3507 call UnitWakeUp(GetEnumUnit())
3508 endfunction
3509
3510 //===========================================================================
3511 function WakePlayerUnits takes player whichPlayer returns nothing
3512 local group g = CreateGroup()
3513 call GroupEnumUnitsOfPlayer(g, whichPlayer, null)
3514 call ForGroup(g, function WakePlayerUnitsEnum)
3515 call DestroyGroup(g)
3516 endfunction
3517
3518 //===========================================================================
3519 function EnableCreepSleepBJ takes boolean enable returns nothing
3520 call SetPlayerState(Player(PLAYER_NEUTRAL_AGGRESSIVE), PLAYER_STATE_NO_CREEP_SLEEP, IntegerTertiaryOp(enable, 0, 1))
3521
3522 // If we're disabling, attempt to wake any already-sleeping creeps.
3523 if (not enable) then
3524 call WakePlayerUnits(Player(PLAYER_NEUTRAL_AGGRESSIVE))
3525 endif
3526 endfunction
3527
3528 //===========================================================================
3529 function UnitGenerateAlarms takes unit whichUnit, boolean generate returns boolean
3530 return UnitIgnoreAlarm(whichUnit, not generate)
3531 endfunction
3532
3533 //===========================================================================
3534 function DoesUnitGenerateAlarms takes unit whichUnit returns boolean
3535 return not UnitIgnoreAlarmToggled(whichUnit)
3536 endfunction
3537
3538 //===========================================================================
3539 function PauseAllUnitsBJEnum takes nothing returns nothing
3540 call PauseUnit( GetEnumUnit(), bj_pauseAllUnitsFlag )
3541 endfunction
3542
3543 //===========================================================================
3544 // Pause all units
3545 function PauseAllUnitsBJ takes boolean pause returns nothing
3546 local integer index
3547 local player indexPlayer
3548 local group g
3549
3550 set bj_pauseAllUnitsFlag = pause
3551 set g = CreateGroup()
3552 set index = 0
3553 loop
3554 set indexPlayer = Player( index )
3555
3556 // If this is a computer slot, pause/resume the AI.
3557 if (GetPlayerController( indexPlayer ) == MAP_CONTROL_COMPUTER) then
3558 call PauseCompAI( indexPlayer, pause )
3559 endif
3560
3561 // Enumerate and unpause every unit owned by the player.
3562 call GroupEnumUnitsOfPlayer( g, indexPlayer, null )
3563 call ForGroup( g, function PauseAllUnitsBJEnum )
3564 call GroupClear( g )
3565
3566 set index = index + 1
3567 exitwhen index == bj_MAX_PLAYER_SLOTS
3568 endloop
3569 call DestroyGroup(g)
3570 endfunction
3571
3572 //===========================================================================
3573 function PauseUnitBJ takes boolean pause, unit whichUnit returns nothing
3574 call PauseUnit(whichUnit, pause)
3575 endfunction
3576
3577 //===========================================================================
3578 function IsUnitPausedBJ takes unit whichUnit returns boolean
3579 return IsUnitPaused(whichUnit)
3580 endfunction
3581
3582 //===========================================================================
3583 function UnitPauseTimedLifeBJ takes boolean flag, unit whichUnit returns nothing
3584 call UnitPauseTimedLife(whichUnit, flag)
3585 endfunction
3586
3587 //===========================================================================
3588 function UnitApplyTimedLifeBJ takes real duration, integer buffId, unit whichUnit returns nothing
3589 call UnitApplyTimedLife(whichUnit, buffId, duration)
3590 endfunction
3591
3592 //===========================================================================
3593 function UnitShareVisionBJ takes boolean share, unit whichUnit, player whichPlayer returns nothing
3594 call UnitShareVision(whichUnit, whichPlayer, share)
3595 endfunction
3596
3597 //===========================================================================
3598 function UnitRemoveBuffsBJ takes integer buffType, unit whichUnit returns nothing
3599 if (buffType == bj_REMOVEBUFFS_POSITIVE) then
3600 call UnitRemoveBuffs(whichUnit, true, false)
3601 elseif (buffType == bj_REMOVEBUFFS_NEGATIVE) then
3602 call UnitRemoveBuffs(whichUnit, false, true)
3603 elseif (buffType == bj_REMOVEBUFFS_ALL) then
3604 call UnitRemoveBuffs(whichUnit, true, true)
3605 elseif (buffType == bj_REMOVEBUFFS_NONTLIFE) then
3606 call UnitRemoveBuffsEx(whichUnit, true, true, false, false, false, true, false)
3607 else
3608 // Unrecognized dispel type - ignore the request.
3609 endif
3610 endfunction
3611
3612 //===========================================================================
3613 function UnitRemoveBuffsExBJ takes integer polarity, integer resist, unit whichUnit, boolean bTLife, boolean bAura returns nothing
3614 local boolean bPos = (polarity == bj_BUFF_POLARITY_EITHER) or (polarity == bj_BUFF_POLARITY_POSITIVE)
3615 local boolean bNeg = (polarity == bj_BUFF_POLARITY_EITHER) or (polarity == bj_BUFF_POLARITY_NEGATIVE)
3616 local boolean bMagic = (resist == bj_BUFF_RESIST_BOTH) or (resist == bj_BUFF_RESIST_MAGIC)
3617 local boolean bPhys = (resist == bj_BUFF_RESIST_BOTH) or (resist == bj_BUFF_RESIST_PHYSICAL)
3618
3619 call UnitRemoveBuffsEx(whichUnit, bPos, bNeg, bMagic, bPhys, bTLife, bAura, false)
3620 endfunction
3621
3622 //===========================================================================
3623 function UnitCountBuffsExBJ takes integer polarity, integer resist, unit whichUnit, boolean bTLife, boolean bAura returns integer
3624 local boolean bPos = (polarity == bj_BUFF_POLARITY_EITHER) or (polarity == bj_BUFF_POLARITY_POSITIVE)
3625 local boolean bNeg = (polarity == bj_BUFF_POLARITY_EITHER) or (polarity == bj_BUFF_POLARITY_NEGATIVE)
3626 local boolean bMagic = (resist == bj_BUFF_RESIST_BOTH) or (resist == bj_BUFF_RESIST_MAGIC)
3627 local boolean bPhys = (resist == bj_BUFF_RESIST_BOTH) or (resist == bj_BUFF_RESIST_PHYSICAL)
3628
3629 return UnitCountBuffsEx(whichUnit, bPos, bNeg, bMagic, bPhys, bTLife, bAura, false)
3630 endfunction
3631
3632 //===========================================================================
3633 function UnitRemoveAbilityBJ takes integer abilityId, unit whichUnit returns boolean
3634 return UnitRemoveAbility(whichUnit, abilityId)
3635 endfunction
3636
3637 //===========================================================================
3638 function UnitAddAbilityBJ takes integer abilityId, unit whichUnit returns boolean
3639 return UnitAddAbility(whichUnit, abilityId)
3640 endfunction
3641
3642 //===========================================================================
3643 function UnitRemoveTypeBJ takes unittype whichType, unit whichUnit returns boolean
3644 return UnitRemoveType(whichUnit, whichType)
3645 endfunction
3646
3647 //===========================================================================
3648 function UnitAddTypeBJ takes unittype whichType, unit whichUnit returns boolean
3649 return UnitAddType(whichUnit, whichType)
3650 endfunction
3651
3652 //===========================================================================
3653 function UnitMakeAbilityPermanentBJ takes boolean permanent, integer abilityId, unit whichUnit returns boolean
3654 return UnitMakeAbilityPermanent(whichUnit, permanent, abilityId)
3655 endfunction
3656
3657 //===========================================================================
3658 function SetUnitExplodedBJ takes unit whichUnit, boolean exploded returns nothing
3659 call SetUnitExploded(whichUnit, exploded)
3660 endfunction
3661
3662 //===========================================================================
3663 function ExplodeUnitBJ takes unit whichUnit returns nothing
3664 call SetUnitExploded(whichUnit, true)
3665 call KillUnit(whichUnit)
3666 endfunction
3667
3668 //===========================================================================
3669 function GetTransportUnitBJ takes nothing returns unit
3670 return GetTransportUnit()
3671 endfunction
3672
3673 //===========================================================================
3674 function GetLoadedUnitBJ takes nothing returns unit
3675 return GetLoadedUnit()
3676 endfunction
3677
3678 //===========================================================================
3679 function IsUnitInTransportBJ takes unit whichUnit, unit whichTransport returns boolean
3680 return IsUnitInTransport(whichUnit, whichTransport)
3681 endfunction
3682
3683 //===========================================================================
3684 function IsUnitLoadedBJ takes unit whichUnit returns boolean
3685 return IsUnitLoaded(whichUnit)
3686 endfunction
3687
3688 //===========================================================================
3689 function IsUnitIllusionBJ takes unit whichUnit returns boolean
3690 return IsUnitIllusion(whichUnit)
3691 endfunction
3692
3693 //===========================================================================
3694 // This attempts to replace a unit with a new unit type by creating a new
3695 // unit of the desired type using the old unit's location, facing, etc.
3696 //
3697 function ReplaceUnitBJ takes unit whichUnit, integer newUnitId, integer unitStateMethod returns unit
3698 local unit oldUnit = whichUnit
3699 local unit newUnit
3700 local boolean wasHidden
3701 local integer index
3702 local item indexItem
3703 local real oldRatio
3704
3705 // If we have bogus data, don't attempt the replace.
3706 if (oldUnit == null) then
3707 set bj_lastReplacedUnit = oldUnit
3708 return oldUnit
3709 endif
3710
3711 // Hide the original unit.
3712 set wasHidden = IsUnitHidden(oldUnit)
3713 call ShowUnit(oldUnit, false)
3714
3715 // Create the replacement unit.
3716 if (newUnitId == 'ugol') then
3717 set newUnit = CreateBlightedGoldmine(GetOwningPlayer(oldUnit), GetUnitX(oldUnit), GetUnitY(oldUnit), GetUnitFacing(oldUnit))
3718 else
3719 set newUnit = CreateUnit(GetOwningPlayer(oldUnit), newUnitId, GetUnitX(oldUnit), GetUnitY(oldUnit), GetUnitFacing(oldUnit))
3720 endif
3721
3722 // Set the unit's life and mana according to the requested method.
3723 if (unitStateMethod == bj_UNIT_STATE_METHOD_RELATIVE) then
3724 // Set the replacement's current/max life ratio to that of the old unit.
3725 // If both units have mana, do the same for mana.
3726 if (GetUnitState(oldUnit, UNIT_STATE_MAX_LIFE) > 0) then
3727 set oldRatio = GetUnitState(oldUnit, UNIT_STATE_LIFE) / GetUnitState(oldUnit, UNIT_STATE_MAX_LIFE)
3728 call SetUnitState(newUnit, UNIT_STATE_LIFE, oldRatio * GetUnitState(newUnit, UNIT_STATE_MAX_LIFE))
3729 endif
3730
3731 if (GetUnitState(oldUnit, UNIT_STATE_MAX_MANA) > 0) and (GetUnitState(newUnit, UNIT_STATE_MAX_MANA) > 0) then
3732 set oldRatio = GetUnitState(oldUnit, UNIT_STATE_MANA) / GetUnitState(oldUnit, UNIT_STATE_MAX_MANA)
3733 call SetUnitState(newUnit, UNIT_STATE_MANA, oldRatio * GetUnitState(newUnit, UNIT_STATE_MAX_MANA))
3734 endif
3735 elseif (unitStateMethod == bj_UNIT_STATE_METHOD_ABSOLUTE) then
3736 // Set the replacement's current life to that of the old unit.
3737 // If the new unit has mana, do the same for mana.
3738 call SetUnitState(newUnit, UNIT_STATE_LIFE, GetUnitState(oldUnit, UNIT_STATE_LIFE))
3739 if (GetUnitState(newUnit, UNIT_STATE_MAX_MANA) > 0) then
3740 call SetUnitState(newUnit, UNIT_STATE_MANA, GetUnitState(oldUnit, UNIT_STATE_MANA))
3741 endif
3742 elseif (unitStateMethod == bj_UNIT_STATE_METHOD_DEFAULTS) then
3743 // The newly created unit should already have default life and mana.
3744 elseif (unitStateMethod == bj_UNIT_STATE_METHOD_MAXIMUM) then
3745 // Use max life and mana.
3746 call SetUnitState(newUnit, UNIT_STATE_LIFE, GetUnitState(newUnit, UNIT_STATE_MAX_LIFE))
3747 call SetUnitState(newUnit, UNIT_STATE_MANA, GetUnitState(newUnit, UNIT_STATE_MAX_MANA))
3748 else
3749 // Unrecognized unit state method - ignore the request.
3750 endif
3751
3752 // Mirror properties of the old unit onto the new unit.
3753 //call PauseUnit(newUnit, IsUnitPaused(oldUnit))
3754 call SetResourceAmount(newUnit, GetResourceAmount(oldUnit))
3755
3756 // If both the old and new units are heroes, handle their hero info.
3757 if (IsUnitType(oldUnit, UNIT_TYPE_HERO) and IsUnitType(newUnit, UNIT_TYPE_HERO)) then
3758 call SetHeroXP(newUnit, GetHeroXP(oldUnit), false)
3759
3760 set index = 0
3761 loop
3762 set indexItem = UnitItemInSlot(oldUnit, index)
3763 if (indexItem != null) then
3764 call UnitRemoveItem(oldUnit, indexItem)
3765 call UnitAddItem(newUnit, indexItem)
3766 endif
3767
3768 set index = index + 1
3769 exitwhen index >= bj_MAX_INVENTORY
3770 endloop
3771 endif
3772
3773 // Remove or kill the original unit. It is sometimes unsafe to remove
3774 // hidden units, so kill the original unit if it was previously hidden.
3775 if wasHidden then
3776 call KillUnit(oldUnit)
3777 call RemoveUnit(oldUnit)
3778 else
3779 call RemoveUnit(oldUnit)
3780 endif
3781
3782 set bj_lastReplacedUnit = newUnit
3783 return newUnit
3784 endfunction
3785
3786 //===========================================================================
3787 function GetLastReplacedUnitBJ takes nothing returns unit
3788 return bj_lastReplacedUnit
3789 endfunction
3790
3791 //===========================================================================
3792 function SetUnitPositionLocFacingBJ takes unit whichUnit, location loc, real facing returns nothing
3793 call SetUnitPositionLoc(whichUnit, loc)
3794 call SetUnitFacing(whichUnit, facing)
3795 endfunction
3796
3797 //===========================================================================
3798 function SetUnitPositionLocFacingLocBJ takes unit whichUnit, location loc, location lookAt returns nothing
3799 call SetUnitPositionLoc(whichUnit, loc)
3800 call SetUnitFacing(whichUnit, AngleBetweenPoints(loc, lookAt))
3801 endfunction
3802
3803 //===========================================================================
3804 function AddItemToStockBJ takes integer itemId, unit whichUnit, integer currentStock, integer stockMax returns nothing
3805 call AddItemToStock(whichUnit, itemId, currentStock, stockMax)
3806 endfunction
3807
3808 //===========================================================================
3809 function AddUnitToStockBJ takes integer unitId, unit whichUnit, integer currentStock, integer stockMax returns nothing
3810 call AddUnitToStock(whichUnit, unitId, currentStock, stockMax)
3811 endfunction
3812
3813 //===========================================================================
3814 function RemoveItemFromStockBJ takes integer itemId, unit whichUnit returns nothing
3815 call RemoveItemFromStock(whichUnit, itemId)
3816 endfunction
3817
3818 //===========================================================================
3819 function RemoveUnitFromStockBJ takes integer unitId, unit whichUnit returns nothing
3820 call RemoveUnitFromStock(whichUnit, unitId)
3821 endfunction
3822
3823 //===========================================================================
3824 function SetUnitUseFoodBJ takes boolean enable, unit whichUnit returns nothing
3825 call SetUnitUseFood(whichUnit, enable)
3826 endfunction
3827
3828 //===========================================================================
3829 function UnitDamagePointLoc takes unit whichUnit, real delay, real radius, location loc, real amount, attacktype whichAttack, damagetype whichDamage returns boolean
3830 return UnitDamagePoint(whichUnit, delay, radius, GetLocationX(loc), GetLocationY(loc), amount, true, false, whichAttack, whichDamage, WEAPON_TYPE_WHOKNOWS)
3831 endfunction
3832
3833 //===========================================================================
3834 function UnitDamageTargetBJ takes unit whichUnit, unit target, real amount, attacktype whichAttack, damagetype whichDamage returns boolean
3835 return UnitDamageTarget(whichUnit, target, amount, true, false, whichAttack, whichDamage, WEAPON_TYPE_WHOKNOWS)
3836 endfunction
3837
3838
3839
3840 //***************************************************************************
3841 //*
3842 //* Destructable Utility Functions
3843 //*
3844 //***************************************************************************
3845
3846 //===========================================================================
3847 function CreateDestructableLoc takes integer objectid, location loc, real facing, real scale, integer variation returns destructable
3848 set bj_lastCreatedDestructable = CreateDestructable(objectid, GetLocationX(loc), GetLocationY(loc), facing, scale, variation)
3849 return bj_lastCreatedDestructable
3850 endfunction
3851
3852 //===========================================================================
3853 function CreateDeadDestructableLocBJ takes integer objectid, location loc, real facing, real scale, integer variation returns destructable
3854 set bj_lastCreatedDestructable = CreateDeadDestructable(objectid, GetLocationX(loc), GetLocationY(loc), facing, scale, variation)
3855 return bj_lastCreatedDestructable
3856 endfunction
3857
3858 //===========================================================================
3859 function GetLastCreatedDestructable takes nothing returns destructable
3860 return bj_lastCreatedDestructable
3861 endfunction
3862
3863 //===========================================================================
3864 function ShowDestructableBJ takes boolean flag, destructable d returns nothing
3865 call ShowDestructable(d, flag)
3866 endfunction
3867
3868 //===========================================================================
3869 function SetDestructableInvulnerableBJ takes destructable d, boolean flag returns nothing
3870 call SetDestructableInvulnerable(d, flag)
3871 endfunction
3872
3873 //===========================================================================
3874 function IsDestructableInvulnerableBJ takes destructable d returns boolean
3875 return IsDestructableInvulnerable(d)
3876 endfunction
3877
3878 //===========================================================================
3879 function GetDestructableLoc takes destructable whichDestructable returns location
3880 return Location(GetDestructableX(whichDestructable), GetDestructableY(whichDestructable))
3881 endfunction
3882
3883 //===========================================================================
3884 function EnumDestructablesInRectAll takes rect r, code actionFunc returns nothing
3885 call EnumDestructablesInRect(r, null, actionFunc)
3886 endfunction
3887
3888 //===========================================================================
3889 function EnumDestructablesInCircleBJFilter takes nothing returns boolean
3890 local location destLoc = GetDestructableLoc(GetFilterDestructable())
3891 local boolean result
3892
3893 set result = DistanceBetweenPoints(destLoc, bj_enumDestructableCenter) <= bj_enumDestructableRadius
3894 call RemoveLocation(destLoc)
3895 return result
3896 endfunction
3897
3898 //===========================================================================
3899 function IsDestructableDeadBJ takes destructable d returns boolean
3900 return GetDestructableLife(d) <= 0
3901 endfunction
3902
3903 //===========================================================================
3904 function IsDestructableAliveBJ takes destructable d returns boolean
3905 return not IsDestructableDeadBJ(d)
3906 endfunction
3907
3908 //===========================================================================
3909 // See GroupPickRandomUnitEnum for the details of this algorithm.
3910 //
3911 function RandomDestructableInRectBJEnum takes nothing returns nothing
3912 set bj_destRandomConsidered = bj_destRandomConsidered + 1
3913 if (GetRandomInt(1,bj_destRandomConsidered) == 1) then
3914 set bj_destRandomCurrentPick = GetEnumDestructable()
3915 endif
3916 endfunction
3917
3918 //===========================================================================
3919 // Picks a random destructable from within a rect, matching a condition
3920 //
3921 function RandomDestructableInRectBJ takes rect r, boolexpr filter returns destructable
3922 set bj_destRandomConsidered = 0
3923 set bj_destRandomCurrentPick = null
3924 call EnumDestructablesInRect(r, filter, function RandomDestructableInRectBJEnum)
3925 call DestroyBoolExpr(filter)
3926 return bj_destRandomCurrentPick
3927 endfunction
3928
3929 //===========================================================================
3930 // Picks a random destructable from within a rect
3931 //
3932 function RandomDestructableInRectSimpleBJ takes rect r returns destructable
3933 return RandomDestructableInRectBJ(r, null)
3934 endfunction
3935
3936 //===========================================================================
3937 // Enumerates within a rect, with a filter to narrow the enumeration down
3938 // objects within a circular area.
3939 //
3940 function EnumDestructablesInCircleBJ takes real radius, location loc, code actionFunc returns nothing
3941 local rect r
3942
3943 if (radius >= 0) then
3944 set bj_enumDestructableCenter = loc
3945 set bj_enumDestructableRadius = radius
3946 set r = GetRectFromCircleBJ(loc, radius)
3947 call EnumDestructablesInRect(r, filterEnumDestructablesInCircleBJ, actionFunc)
3948 call RemoveRect(r)
3949 endif
3950 endfunction
3951
3952 //===========================================================================
3953 function SetDestructableLifePercentBJ takes destructable d, real percent returns nothing
3954 call SetDestructableLife(d, GetDestructableMaxLife(d) * percent * 0.01)
3955 endfunction
3956
3957 //===========================================================================
3958 function SetDestructableMaxLifeBJ takes destructable d, real max returns nothing
3959 call SetDestructableMaxLife(d, max)
3960 endfunction
3961
3962 //===========================================================================
3963 function ModifyGateBJ takes integer gateOperation, destructable d returns nothing
3964 if (gateOperation == bj_GATEOPERATION_CLOSE) then
3965 if (GetDestructableLife(d) <= 0) then
3966 call DestructableRestoreLife(d, GetDestructableMaxLife(d), true)
3967 endif
3968 call SetDestructableAnimation(d, "stand")
3969 elseif (gateOperation == bj_GATEOPERATION_OPEN) then
3970 if (GetDestructableLife(d) > 0) then
3971 call KillDestructable(d)
3972 endif
3973 call SetDestructableAnimation(d, "death alternate")
3974 elseif (gateOperation == bj_GATEOPERATION_DESTROY) then
3975 if (GetDestructableLife(d) > 0) then
3976 call KillDestructable(d)
3977 endif
3978 call SetDestructableAnimation(d, "death")
3979 else
3980 // Unrecognized gate state - ignore the request.
3981 endif
3982 endfunction
3983
3984 //===========================================================================
3985 // Determine the elevator's height from its occlusion height.
3986 //
3987 function GetElevatorHeight takes destructable d returns integer
3988 local integer height
3989
3990 set height = 1 + R2I(GetDestructableOccluderHeight(d) / bj_CLIFFHEIGHT)
3991 if (height < 1) or (height > 3) then
3992 set height = 1
3993 endif
3994 return height
3995 endfunction
3996
3997 //===========================================================================
3998 // To properly animate an elevator, we must know not only what height we
3999 // want to change to, but also what height we are currently at. This code
4000 // determines the elevator's current height from its occlusion height.
4001 // Arbitrarily changing an elevator's occlusion height is thus inadvisable.
4002 //
4003 function ChangeElevatorHeight takes destructable d, integer newHeight returns nothing
4004 local integer oldHeight
4005
4006 // Cap the new height within the supported range.
4007 set newHeight = IMaxBJ(1, newHeight)
4008 set newHeight = IMinBJ(3, newHeight)
4009
4010 // Find out what height the elevator is already at.
4011 set oldHeight = GetElevatorHeight(d)
4012
4013 // Set the elevator's occlusion height.
4014 call SetDestructableOccluderHeight(d, bj_CLIFFHEIGHT*(newHeight-1))
4015
4016 if (newHeight == 1) then
4017 if (oldHeight == 2) then
4018 call SetDestructableAnimation(d, "birth")
4019 call QueueDestructableAnimation(d, "stand")
4020 elseif (oldHeight == 3) then
4021 call SetDestructableAnimation(d, "birth third")
4022 call QueueDestructableAnimation(d, "stand")
4023 else
4024 // Unrecognized old height - snap to new height.
4025 call SetDestructableAnimation(d, "stand")
4026 endif
4027 elseif (newHeight == 2) then
4028 if (oldHeight == 1) then
4029 call SetDestructableAnimation(d, "death")
4030 call QueueDestructableAnimation(d, "stand second")
4031 elseif (oldHeight == 3) then
4032 call SetDestructableAnimation(d, "birth second")
4033 call QueueDestructableAnimation(d, "stand second")
4034 else
4035 // Unrecognized old height - snap to new height.
4036 call SetDestructableAnimation(d, "stand second")
4037 endif
4038 elseif (newHeight == 3) then
4039 if (oldHeight == 1) then
4040 call SetDestructableAnimation(d, "death third")
4041 call QueueDestructableAnimation(d, "stand third")
4042 elseif (oldHeight == 2) then
4043 call SetDestructableAnimation(d, "death second")
4044 call QueueDestructableAnimation(d, "stand third")
4045 else
4046 // Unrecognized old height - snap to new height.
4047 call SetDestructableAnimation(d, "stand third")
4048 endif
4049 else
4050 // Unrecognized new height - ignore the request.
4051 endif
4052 endfunction
4053
4054 //===========================================================================
4055 // Grab the unit and throw his own coords in his face, forcing him to push
4056 // and shove until he finds a spot where noone will bother him.
4057 //
4058 function NudgeUnitsInRectEnum takes nothing returns nothing
4059 local unit nudgee = GetEnumUnit()
4060
4061 call SetUnitPosition(nudgee, GetUnitX(nudgee), GetUnitY(nudgee))
4062 endfunction
4063
4064 //===========================================================================
4065 function NudgeItemsInRectEnum takes nothing returns nothing
4066 local item nudgee = GetEnumItem()
4067
4068 call SetItemPosition(nudgee, GetItemX(nudgee), GetItemY(nudgee))
4069 endfunction
4070
4071 //===========================================================================
4072 // Nudge the items and units within a given rect ever so gently, so as to
4073 // encourage them to find locations where they can peacefully coexist with
4074 // pathing restrictions and live happy, fruitful lives.
4075 //
4076 function NudgeObjectsInRect takes rect nudgeArea returns nothing
4077 local group g
4078
4079 set g = CreateGroup()
4080 call GroupEnumUnitsInRect(g, nudgeArea, null)
4081 call ForGroup(g, function NudgeUnitsInRectEnum)
4082 call DestroyGroup(g)
4083
4084 call EnumItemsInRect(nudgeArea, null, function NudgeItemsInRectEnum)
4085 endfunction
4086
4087 //===========================================================================
4088 function NearbyElevatorExistsEnum takes nothing returns nothing
4089 local destructable d = GetEnumDestructable()
4090 local integer dType = GetDestructableTypeId(d)
4091
4092 if (dType == bj_ELEVATOR_CODE01) or (dType == bj_ELEVATOR_CODE02) then
4093 set bj_elevatorNeighbor = d
4094 endif
4095 endfunction
4096
4097 //===========================================================================
4098 function NearbyElevatorExists takes real x, real y returns boolean
4099 local real findThreshold = 32
4100 local rect r
4101
4102 // If another elevator is overlapping this one, ignore the wall.
4103 set r = Rect(x - findThreshold, y - findThreshold, x + findThreshold, y + findThreshold)
4104 set bj_elevatorNeighbor = null
4105 call EnumDestructablesInRect(r, null, function NearbyElevatorExistsEnum)
4106 call RemoveRect(r)
4107
4108 return bj_elevatorNeighbor != null
4109 endfunction
4110
4111 //===========================================================================
4112 function FindElevatorWallBlockerEnum takes nothing returns nothing
4113 set bj_elevatorWallBlocker = GetEnumDestructable()
4114 endfunction
4115
4116 //===========================================================================
4117 // This toggles pathing on or off for one wall of an elevator by killing
4118 // or reviving a pathing blocker at the appropriate location (and creating
4119 // the pathing blocker in the first place, if it does not yet exist).
4120 //
4121 function ChangeElevatorWallBlocker takes real x, real y, real facing, boolean open returns nothing
4122 local destructable blocker = null
4123 local real findThreshold = 32
4124 local real nudgeLength = 4.25 * bj_CELLWIDTH
4125 local real nudgeWidth = 1.25 * bj_CELLWIDTH
4126 local rect r
4127
4128 // Search for the pathing blocker within the general area.
4129 set r = Rect(x - findThreshold, y - findThreshold, x + findThreshold, y + findThreshold)
4130 set bj_elevatorWallBlocker = null
4131 call EnumDestructablesInRect(r, null, function FindElevatorWallBlockerEnum)
4132 call RemoveRect(r)
4133 set blocker = bj_elevatorWallBlocker
4134
4135 // Ensure that the blocker exists.
4136 if (blocker == null) then
4137 set blocker = CreateDeadDestructable(bj_ELEVATOR_BLOCKER_CODE, x, y, facing, 1, 0)
4138 elseif (GetDestructableTypeId(blocker) != bj_ELEVATOR_BLOCKER_CODE) then
4139 // If a different destructible exists in the blocker's spot, ignore
4140 // the request. (Two destructibles cannot occupy the same location
4141 // on the map, so we cannot create an elevator blocker here.)
4142 return
4143 endif
4144
4145 if (open) then
4146 // Ensure that the blocker is dead.
4147 if (GetDestructableLife(blocker) > 0) then
4148 call KillDestructable(blocker)
4149 endif
4150 else
4151 // Ensure that the blocker is alive.
4152 if (GetDestructableLife(blocker) <= 0) then
4153 call DestructableRestoreLife(blocker, GetDestructableMaxLife(blocker), false)
4154 endif
4155
4156 // Nudge any objects standing in the blocker's way.
4157 if (facing == 0) then
4158 set r = Rect(x - nudgeWidth/2, y - nudgeLength/2, x + nudgeWidth/2, y + nudgeLength/2)
4159 call NudgeObjectsInRect(r)
4160 call RemoveRect(r)
4161 elseif (facing == 90) then
4162 set r = Rect(x - nudgeLength/2, y - nudgeWidth/2, x + nudgeLength/2, y + nudgeWidth/2)
4163 call NudgeObjectsInRect(r)
4164 call RemoveRect(r)
4165 else
4166 // Unrecognized blocker angle - don't nudge anything.
4167 endif
4168 endif
4169 endfunction
4170
4171 //===========================================================================
4172 function ChangeElevatorWalls takes boolean open, integer walls, destructable d returns nothing
4173 local real x = GetDestructableX(d)
4174 local real y = GetDestructableY(d)
4175 local real distToBlocker = 192
4176 local real distToNeighbor = 256
4177
4178 if (walls == bj_ELEVATOR_WALL_TYPE_ALL) or (walls == bj_ELEVATOR_WALL_TYPE_EAST) then
4179 if (not NearbyElevatorExists(x + distToNeighbor, y)) then
4180 call ChangeElevatorWallBlocker(x + distToBlocker, y, 0, open)
4181 endif
4182 endif
4183
4184 if (walls == bj_ELEVATOR_WALL_TYPE_ALL) or (walls == bj_ELEVATOR_WALL_TYPE_NORTH) then
4185 if (not NearbyElevatorExists(x, y + distToNeighbor)) then
4186 call ChangeElevatorWallBlocker(x, y + distToBlocker, 90, open)
4187 endif
4188 endif
4189
4190 if (walls == bj_ELEVATOR_WALL_TYPE_ALL) or (walls == bj_ELEVATOR_WALL_TYPE_SOUTH) then
4191 if (not NearbyElevatorExists(x, y - distToNeighbor)) then
4192 call ChangeElevatorWallBlocker(x, y - distToBlocker, 90, open)
4193 endif
4194 endif
4195
4196 if (walls == bj_ELEVATOR_WALL_TYPE_ALL) or (walls == bj_ELEVATOR_WALL_TYPE_WEST) then
4197 if (not NearbyElevatorExists(x - distToNeighbor, y)) then
4198 call ChangeElevatorWallBlocker(x - distToBlocker, y, 0, open)
4199 endif
4200 endif
4201 endfunction
4202
4203
4204
4205 //***************************************************************************
4206 //*
4207 //* Neutral Building Utility Functions
4208 //*
4209 //***************************************************************************
4210
4211 //===========================================================================
4212 function WaygateActivateBJ takes boolean activate, unit waygate returns nothing
4213 call WaygateActivate(waygate, activate)
4214 endfunction
4215
4216 //===========================================================================
4217 function WaygateIsActiveBJ takes unit waygate returns boolean
4218 return WaygateIsActive(waygate)
4219 endfunction
4220
4221 //===========================================================================
4222 function WaygateSetDestinationLocBJ takes unit waygate, location loc returns nothing
4223 call WaygateSetDestination(waygate, GetLocationX(loc), GetLocationY(loc))
4224 endfunction
4225
4226 //===========================================================================
4227 function WaygateGetDestinationLocBJ takes unit waygate returns location
4228 return Location(WaygateGetDestinationX(waygate), WaygateGetDestinationY(waygate))
4229 endfunction
4230
4231 //===========================================================================
4232 function UnitSetUsesAltIconBJ takes boolean flag, unit whichUnit returns nothing
4233 call UnitSetUsesAltIcon(whichUnit, flag)
4234 endfunction
4235
4236
4237
4238 //***************************************************************************
4239 //*
4240 //* UI Utility Functions
4241 //*
4242 //***************************************************************************
4243
4244 //===========================================================================
4245 function ForceUIKeyBJ takes player whichPlayer, string key returns nothing
4246 if (GetLocalPlayer() == whichPlayer) then
4247 // Use only local code (no net traffic) within this block to avoid desyncs.
4248 call ForceUIKey(key)
4249 endif
4250 endfunction
4251
4252 //===========================================================================
4253 function ForceUICancelBJ takes player whichPlayer returns nothing
4254 if (GetLocalPlayer() == whichPlayer) then
4255 // Use only local code (no net traffic) within this block to avoid desyncs.
4256 call ForceUICancel()
4257 endif
4258 endfunction
4259
4260
4261
4262 //***************************************************************************
4263 //*
4264 //* Group and Force Utility Functions
4265 //*
4266 //***************************************************************************
4267
4268 //===========================================================================
4269 function ForGroupBJ takes group whichGroup, code callback returns nothing
4270 // If the user wants the group destroyed, remember that fact and clear
4271 // the flag, in case it is used again in the callback.
4272 local boolean wantDestroy = bj_wantDestroyGroup
4273 set bj_wantDestroyGroup = false
4274
4275 call ForGroup(whichGroup, callback)
4276
4277 // If the user wants the group destroyed, do so now.
4278 if (wantDestroy) then
4279 call DestroyGroup(whichGroup)
4280 endif
4281 endfunction
4282
4283 //===========================================================================
4284 function GroupAddUnitSimple takes unit whichUnit, group whichGroup returns nothing
4285 call GroupAddUnit(whichGroup, whichUnit)
4286 endfunction
4287
4288 //===========================================================================
4289 function GroupRemoveUnitSimple takes unit whichUnit, group whichGroup returns nothing
4290 call GroupRemoveUnit(whichGroup, whichUnit)
4291 endfunction
4292
4293 //===========================================================================
4294 function GroupAddGroupEnum takes nothing returns nothing
4295 call GroupAddUnit(bj_groupAddGroupDest, GetEnumUnit())
4296 endfunction
4297
4298 //===========================================================================
4299 function GroupAddGroup takes group sourceGroup, group destGroup returns nothing
4300 // If the user wants the group destroyed, remember that fact and clear
4301 // the flag, in case it is used again in the callback.
4302 local boolean wantDestroy = bj_wantDestroyGroup
4303 set bj_wantDestroyGroup = false
4304
4305 set bj_groupAddGroupDest = destGroup
4306 call ForGroup(sourceGroup, function GroupAddGroupEnum)
4307
4308 // If the user wants the group destroyed, do so now.
4309 if (wantDestroy) then
4310 call DestroyGroup(sourceGroup)
4311 endif
4312 endfunction
4313
4314 //===========================================================================
4315 function GroupRemoveGroupEnum takes nothing returns nothing
4316 call GroupRemoveUnit(bj_groupRemoveGroupDest, GetEnumUnit())
4317 endfunction
4318
4319 //===========================================================================
4320 function GroupRemoveGroup takes group sourceGroup, group destGroup returns nothing
4321 // If the user wants the group destroyed, remember that fact and clear
4322 // the flag, in case it is used again in the callback.
4323 local boolean wantDestroy = bj_wantDestroyGroup
4324 set bj_wantDestroyGroup = false
4325
4326 set bj_groupRemoveGroupDest = destGroup
4327 call ForGroup(sourceGroup, function GroupRemoveGroupEnum)
4328
4329 // If the user wants the group destroyed, do so now.
4330 if (wantDestroy) then
4331 call DestroyGroup(sourceGroup)
4332 endif
4333 endfunction
4334
4335 //===========================================================================
4336 function ForceAddPlayerSimple takes player whichPlayer, force whichForce returns nothing
4337 call ForceAddPlayer(whichForce, whichPlayer)
4338 endfunction
4339
4340 //===========================================================================
4341 function ForceRemovePlayerSimple takes player whichPlayer, force whichForce returns nothing
4342 call ForceRemovePlayer(whichForce, whichPlayer)
4343 endfunction
4344
4345 //===========================================================================
4346 // Consider each unit, one at a time, keeping a "current pick". Once all units
4347 // are considered, this "current pick" will be the resulting random unit.
4348 //
4349 // The chance of picking a given unit over the "current pick" is 1/N, where N is
4350 // the number of units considered thusfar (including the current consideration).
4351 //
4352 function GroupPickRandomUnitEnum takes nothing returns nothing
4353 set bj_groupRandomConsidered = bj_groupRandomConsidered + 1
4354 if (GetRandomInt(1,bj_groupRandomConsidered) == 1) then
4355 set bj_groupRandomCurrentPick = GetEnumUnit()
4356 endif
4357 endfunction
4358
4359 //===========================================================================
4360 // Picks a random unit from a group.
4361 //
4362 function GroupPickRandomUnit takes group whichGroup returns unit
4363 // If the user wants the group destroyed, remember that fact and clear
4364 // the flag, in case it is used again in the callback.
4365 local boolean wantDestroy = bj_wantDestroyGroup
4366 set bj_wantDestroyGroup = false
4367
4368 set bj_groupRandomConsidered = 0
4369 set bj_groupRandomCurrentPick = null
4370 call ForGroup(whichGroup, function GroupPickRandomUnitEnum)
4371
4372 // If the user wants the group destroyed, do so now.
4373 if (wantDestroy) then
4374 call DestroyGroup(whichGroup)
4375 endif
4376 return bj_groupRandomCurrentPick
4377 endfunction
4378
4379 //===========================================================================
4380 // See GroupPickRandomUnitEnum for the details of this algorithm.
4381 //
4382 function ForcePickRandomPlayerEnum takes nothing returns nothing
4383 set bj_forceRandomConsidered = bj_forceRandomConsidered + 1
4384 if (GetRandomInt(1,bj_forceRandomConsidered) == 1) then
4385 set bj_forceRandomCurrentPick = GetEnumPlayer()
4386 endif
4387 endfunction
4388
4389 //===========================================================================
4390 // Picks a random player from a force.
4391 //
4392 function ForcePickRandomPlayer takes force whichForce returns player
4393 set bj_forceRandomConsidered = 0
4394 set bj_forceRandomCurrentPick = null
4395 call ForForce(whichForce, function ForcePickRandomPlayerEnum)
4396 return bj_forceRandomCurrentPick
4397 endfunction
4398
4399 //===========================================================================
4400 function EnumUnitsSelected takes player whichPlayer, boolexpr enumFilter, code enumAction returns nothing
4401 local group g = CreateGroup()
4402 call SyncSelections()
4403 call GroupEnumUnitsSelected(g, whichPlayer, enumFilter)
4404 call DestroyBoolExpr(enumFilter)
4405 call ForGroup(g, enumAction)
4406 call DestroyGroup(g)
4407 endfunction
4408
4409 //===========================================================================
4410 function GetUnitsInRectMatching takes rect r, boolexpr filter returns group
4411 local group g = CreateGroup()
4412 call GroupEnumUnitsInRect(g, r, filter)
4413 call DestroyBoolExpr(filter)
4414 return g
4415 endfunction
4416
4417 //===========================================================================
4418 function GetUnitsInRectAll takes rect r returns group
4419 return GetUnitsInRectMatching(r, null)
4420 endfunction
4421
4422 //===========================================================================
4423 function GetUnitsInRectOfPlayerFilter takes nothing returns boolean
4424 return GetOwningPlayer(GetFilterUnit()) == bj_groupEnumOwningPlayer
4425 endfunction
4426
4427 //===========================================================================
4428 function GetUnitsInRectOfPlayer takes rect r, player whichPlayer returns group
4429 local group g = CreateGroup()
4430 set bj_groupEnumOwningPlayer = whichPlayer
4431 call GroupEnumUnitsInRect(g, r, filterGetUnitsInRectOfPlayer)
4432 return g
4433 endfunction
4434
4435 //===========================================================================
4436 function GetUnitsInRangeOfLocMatching takes real radius, location whichLocation, boolexpr filter returns group
4437 local group g = CreateGroup()
4438 call GroupEnumUnitsInRangeOfLoc(g, whichLocation, radius, filter)
4439 call DestroyBoolExpr(filter)
4440 return g
4441 endfunction
4442
4443 //===========================================================================
4444 function GetUnitsInRangeOfLocAll takes real radius, location whichLocation returns group
4445 return GetUnitsInRangeOfLocMatching(radius, whichLocation, null)
4446 endfunction
4447
4448 //===========================================================================
4449 function GetUnitsOfTypeIdAllFilter takes nothing returns boolean
4450 return GetUnitTypeId(GetFilterUnit()) == bj_groupEnumTypeId
4451 endfunction
4452
4453 //===========================================================================
4454 function GetUnitsOfTypeIdAll takes integer unitid returns group
4455 local group result = CreateGroup()
4456 local group g = CreateGroup()
4457 local integer index
4458
4459 set index = 0
4460 loop
4461 set bj_groupEnumTypeId = unitid
4462 call GroupClear(g)
4463 call GroupEnumUnitsOfPlayer(g, Player(index), filterGetUnitsOfTypeIdAll)
4464 call GroupAddGroup(g, result)
4465
4466 set index = index + 1
4467 exitwhen index == bj_MAX_PLAYER_SLOTS
4468 endloop
4469 call DestroyGroup(g)
4470
4471 return result
4472 endfunction
4473
4474 //===========================================================================
4475 function GetUnitsOfPlayerMatching takes player whichPlayer, boolexpr filter returns group
4476 local group g = CreateGroup()
4477 call GroupEnumUnitsOfPlayer(g, whichPlayer, filter)
4478 call DestroyBoolExpr(filter)
4479 return g
4480 endfunction
4481
4482 //===========================================================================
4483 function GetUnitsOfPlayerAll takes player whichPlayer returns group
4484 return GetUnitsOfPlayerMatching(whichPlayer, null)
4485 endfunction
4486
4487 //===========================================================================
4488 function GetUnitsOfPlayerAndTypeIdFilter takes nothing returns boolean
4489 return GetUnitTypeId(GetFilterUnit()) == bj_groupEnumTypeId
4490 endfunction
4491
4492 //===========================================================================
4493 function GetUnitsOfPlayerAndTypeId takes player whichPlayer, integer unitid returns group
4494 local group g = CreateGroup()
4495 set bj_groupEnumTypeId = unitid
4496 call GroupEnumUnitsOfPlayer(g, whichPlayer, filterGetUnitsOfPlayerAndTypeId)
4497 return g
4498 endfunction
4499
4500 //===========================================================================
4501 function GetUnitsSelectedAll takes player whichPlayer returns group
4502 local group g = CreateGroup()
4503 call SyncSelections()
4504 call GroupEnumUnitsSelected(g, whichPlayer, null)
4505 return g
4506 endfunction
4507
4508 //===========================================================================
4509 function GetForceOfPlayer takes player whichPlayer returns force
4510 local force f = CreateForce()
4511 call ForceAddPlayer(f, whichPlayer)
4512 return f
4513 endfunction
4514
4515 //===========================================================================
4516 function GetPlayersAll takes nothing returns force
4517 return bj_FORCE_ALL_PLAYERS
4518 endfunction
4519
4520 //===========================================================================
4521 function GetPlayersByMapControl takes mapcontrol whichControl returns force
4522 local force f = CreateForce()
4523 local integer playerIndex
4524 local player indexPlayer
4525
4526 set playerIndex = 0
4527 loop
4528 set indexPlayer = Player(playerIndex)
4529 if GetPlayerController(indexPlayer) == whichControl then
4530 call ForceAddPlayer(f, indexPlayer)
4531 endif
4532
4533 set playerIndex = playerIndex + 1
4534 exitwhen playerIndex == bj_MAX_PLAYER_SLOTS
4535 endloop
4536
4537 return f
4538 endfunction
4539
4540 //===========================================================================
4541 function GetPlayersAllies takes player whichPlayer returns force
4542 local force f = CreateForce()
4543 call ForceEnumAllies(f, whichPlayer, null)
4544 return f
4545 endfunction
4546
4547 //===========================================================================
4548 function GetPlayersEnemies takes player whichPlayer returns force
4549 local force f = CreateForce()
4550 call ForceEnumEnemies(f, whichPlayer, null)
4551 return f
4552 endfunction
4553
4554 //===========================================================================
4555 function GetPlayersMatching takes boolexpr filter returns force
4556 local force f = CreateForce()
4557 call ForceEnumPlayers(f, filter)
4558 call DestroyBoolExpr(filter)
4559 return f
4560 endfunction
4561
4562 //===========================================================================
4563 function CountUnitsInGroupEnum takes nothing returns nothing
4564 set bj_groupCountUnits = bj_groupCountUnits + 1
4565 endfunction
4566
4567 //===========================================================================
4568 function CountUnitsInGroup takes group g returns integer
4569 // If the user wants the group destroyed, remember that fact and clear
4570 // the flag, in case it is used again in the callback.
4571 local boolean wantDestroy = bj_wantDestroyGroup
4572 set bj_wantDestroyGroup = false
4573
4574 set bj_groupCountUnits = 0
4575 call ForGroup(g, function CountUnitsInGroupEnum)
4576
4577 // If the user wants the group destroyed, do so now.
4578 if (wantDestroy) then
4579 call DestroyGroup(g)
4580 endif
4581 return bj_groupCountUnits
4582 endfunction
4583
4584 //===========================================================================
4585 function CountPlayersInForceEnum takes nothing returns nothing
4586 set bj_forceCountPlayers = bj_forceCountPlayers + 1
4587 endfunction
4588
4589 //===========================================================================
4590 function CountPlayersInForceBJ takes force f returns integer
4591 set bj_forceCountPlayers = 0
4592 call ForForce(f, function CountPlayersInForceEnum)
4593 return bj_forceCountPlayers
4594 endfunction
4595
4596 //===========================================================================
4597 function GetRandomSubGroupEnum takes nothing returns nothing
4598 if (bj_randomSubGroupWant > 0) then
4599 if (bj_randomSubGroupWant >= bj_randomSubGroupTotal) or (GetRandomReal(0,1) < bj_randomSubGroupChance) then
4600 // We either need every remaining unit, or the unit passed its chance check.
4601 call GroupAddUnit(bj_randomSubGroupGroup, GetEnumUnit())
4602 set bj_randomSubGroupWant = bj_randomSubGroupWant - 1
4603 endif
4604 endif
4605 set bj_randomSubGroupTotal = bj_randomSubGroupTotal - 1
4606 endfunction
4607
4608 //===========================================================================
4609 function GetRandomSubGroup takes integer count, group sourceGroup returns group
4610 local group g = CreateGroup()
4611
4612 set bj_randomSubGroupGroup = g
4613 set bj_randomSubGroupWant = count
4614 set bj_randomSubGroupTotal = CountUnitsInGroup(sourceGroup)
4615
4616 if (bj_randomSubGroupWant <= 0 or bj_randomSubGroupTotal <= 0) then
4617 return g
4618 endif
4619
4620 set bj_randomSubGroupChance = I2R(bj_randomSubGroupWant) / I2R(bj_randomSubGroupTotal)
4621 call ForGroup(sourceGroup, function GetRandomSubGroupEnum)
4622 return g
4623 endfunction
4624
4625 //===========================================================================
4626 function LivingPlayerUnitsOfTypeIdFilter takes nothing returns boolean
4627 local unit filterUnit = GetFilterUnit()
4628 return IsUnitAliveBJ(filterUnit) and GetUnitTypeId(filterUnit) == bj_livingPlayerUnitsTypeId
4629 endfunction
4630
4631 //===========================================================================
4632 function CountLivingPlayerUnitsOfTypeId takes integer unitId, player whichPlayer returns integer
4633 local group g
4634 local integer matchedCount
4635
4636 set g = CreateGroup()
4637 set bj_livingPlayerUnitsTypeId = unitId
4638 call GroupEnumUnitsOfPlayer(g, whichPlayer, filterLivingPlayerUnitsOfTypeId)
4639 set matchedCount = CountUnitsInGroup(g)
4640 call DestroyGroup(g)
4641
4642 return matchedCount
4643 endfunction
4644
4645
4646
4647 //***************************************************************************
4648 //*
4649 //* Animation Utility Functions
4650 //*
4651 //***************************************************************************
4652
4653 //===========================================================================
4654 function ResetUnitAnimation takes unit whichUnit returns nothing
4655 call SetUnitAnimation(whichUnit, "stand")
4656 endfunction
4657
4658 //===========================================================================
4659 function SetUnitTimeScalePercent takes unit whichUnit, real percentScale returns nothing
4660 call SetUnitTimeScale(whichUnit, percentScale * 0.01)
4661 endfunction
4662
4663 //===========================================================================
4664 function SetUnitScalePercent takes unit whichUnit, real percentScaleX, real percentScaleY, real percentScaleZ returns nothing
4665 call SetUnitScale(whichUnit, percentScaleX * 0.01, percentScaleY * 0.01, percentScaleZ * 0.01)
4666 endfunction
4667
4668 //===========================================================================
4669 // This version differs from the common.j interface in that the alpha value
4670 // is reversed so as to be displayed as transparency, and all four parameters
4671 // are treated as percentages rather than bytes.
4672 //
4673 function SetUnitVertexColorBJ takes unit whichUnit, real red, real green, real blue, real transparency returns nothing
4674 call SetUnitVertexColor(whichUnit, PercentTo255(red), PercentTo255(green), PercentTo255(blue), PercentTo255(100.0-transparency))
4675 endfunction
4676
4677 //===========================================================================
4678 function UnitAddIndicatorBJ takes unit whichUnit, real red, real green, real blue, real transparency returns nothing
4679 call AddIndicator(whichUnit, PercentTo255(red), PercentTo255(green), PercentTo255(blue), PercentTo255(100.0-transparency))
4680 endfunction
4681
4682 //===========================================================================
4683 function DestructableAddIndicatorBJ takes destructable whichDestructable, real red, real green, real blue, real transparency returns nothing
4684 call AddIndicator(whichDestructable, PercentTo255(red), PercentTo255(green), PercentTo255(blue), PercentTo255(100.0-transparency))
4685 endfunction
4686
4687 //===========================================================================
4688 function ItemAddIndicatorBJ takes item whichItem, real red, real green, real blue, real transparency returns nothing
4689 call AddIndicator(whichItem, PercentTo255(red), PercentTo255(green), PercentTo255(blue), PercentTo255(100.0-transparency))
4690 endfunction
4691
4692 //===========================================================================
4693 // Sets a unit's facing to point directly at a location.
4694 //
4695 function SetUnitFacingToFaceLocTimed takes unit whichUnit, location target, real duration returns nothing
4696 local location unitLoc = GetUnitLoc(whichUnit)
4697
4698 call SetUnitFacingTimed(whichUnit, AngleBetweenPoints(unitLoc, target), duration)
4699 call RemoveLocation(unitLoc)
4700 endfunction
4701
4702 //===========================================================================
4703 // Sets a unit's facing to point directly at another unit.
4704 //
4705 function SetUnitFacingToFaceUnitTimed takes unit whichUnit, unit target, real duration returns nothing
4706 local location unitLoc = GetUnitLoc(target)
4707
4708 call SetUnitFacingToFaceLocTimed(whichUnit, unitLoc, duration)
4709 call RemoveLocation(unitLoc)
4710 endfunction
4711
4712 //===========================================================================
4713 function QueueUnitAnimationBJ takes unit whichUnit, string whichAnimation returns nothing
4714 call QueueUnitAnimation(whichUnit, whichAnimation)
4715 endfunction
4716
4717 //===========================================================================
4718 function SetDestructableAnimationBJ takes destructable d, string whichAnimation returns nothing
4719 call SetDestructableAnimation(d, whichAnimation)
4720 endfunction
4721
4722 //===========================================================================
4723 function QueueDestructableAnimationBJ takes destructable d, string whichAnimation returns nothing
4724 call QueueDestructableAnimation(d, whichAnimation)
4725 endfunction
4726
4727 //===========================================================================
4728 function SetDestAnimationSpeedPercent takes destructable d, real percentScale returns nothing
4729 call SetDestructableAnimationSpeed(d, percentScale * 0.01)
4730 endfunction
4731
4732
4733
4734 //***************************************************************************
4735 //*
4736 //* Dialog Utility Functions
4737 //*
4738 //***************************************************************************
4739
4740 //===========================================================================
4741 function DialogDisplayBJ takes boolean flag, dialog whichDialog, player whichPlayer returns nothing
4742 call DialogDisplay(whichPlayer, whichDialog, flag)
4743 endfunction
4744
4745 //===========================================================================
4746 function DialogSetMessageBJ takes dialog whichDialog, string message returns nothing
4747 call DialogSetMessage(whichDialog, message)
4748 endfunction
4749
4750 //===========================================================================
4751 function DialogAddButtonBJ takes dialog whichDialog, string buttonText returns button
4752 set bj_lastCreatedButton = DialogAddButton(whichDialog, buttonText,0)
4753 return bj_lastCreatedButton
4754 endfunction
4755
4756 //===========================================================================
4757 function DialogAddButtonWithHotkeyBJ takes dialog whichDialog, string buttonText, integer hotkey returns button
4758 set bj_lastCreatedButton = DialogAddButton(whichDialog, buttonText,hotkey)
4759 return bj_lastCreatedButton
4760 endfunction
4761
4762 //===========================================================================
4763 function DialogClearBJ takes dialog whichDialog returns nothing
4764 call DialogClear(whichDialog)
4765 endfunction
4766
4767 //===========================================================================
4768 function GetLastCreatedButtonBJ takes nothing returns button
4769 return bj_lastCreatedButton
4770 endfunction
4771
4772 //===========================================================================
4773 function GetClickedButtonBJ takes nothing returns button
4774 return GetClickedButton()
4775 endfunction
4776
4777 //===========================================================================
4778 function GetClickedDialogBJ takes nothing returns dialog
4779 return GetClickedDialog()
4780 endfunction
4781
4782
4783
4784 //***************************************************************************
4785 //*
4786 //* Alliance Utility Functions
4787 //*
4788 //***************************************************************************
4789
4790 //===========================================================================
4791 function SetPlayerAllianceBJ takes player sourcePlayer, alliancetype whichAllianceSetting, boolean value, player otherPlayer returns nothing
4792 // Prevent players from attempting to ally with themselves.
4793 if (sourcePlayer == otherPlayer) then
4794 return
4795 endif
4796
4797 call SetPlayerAlliance(sourcePlayer, otherPlayer, whichAllianceSetting, value)
4798 endfunction
4799
4800 //===========================================================================
4801 // Set all flags used by the in-game "Ally" checkbox.
4802 //
4803 function SetPlayerAllianceStateAllyBJ takes player sourcePlayer, player otherPlayer, boolean flag returns nothing
4804 call SetPlayerAlliance(sourcePlayer, otherPlayer, ALLIANCE_PASSIVE, flag)
4805 call SetPlayerAlliance(sourcePlayer, otherPlayer, ALLIANCE_HELP_REQUEST, flag)
4806 call SetPlayerAlliance(sourcePlayer, otherPlayer, ALLIANCE_HELP_RESPONSE, flag)
4807 call SetPlayerAlliance(sourcePlayer, otherPlayer, ALLIANCE_SHARED_XP, flag)
4808 call SetPlayerAlliance(sourcePlayer, otherPlayer, ALLIANCE_SHARED_SPELLS, flag)
4809 endfunction
4810
4811 //===========================================================================
4812 // Set all flags used by the in-game "Shared Vision" checkbox.
4813 //
4814 function SetPlayerAllianceStateVisionBJ takes player sourcePlayer, player otherPlayer, boolean flag returns nothing
4815 call SetPlayerAlliance(sourcePlayer, otherPlayer, ALLIANCE_SHARED_VISION, flag)
4816 endfunction
4817
4818 //===========================================================================
4819 // Set all flags used by the in-game "Shared Units" checkbox.
4820 //
4821 function SetPlayerAllianceStateControlBJ takes player sourcePlayer, player otherPlayer, boolean flag returns nothing
4822 call SetPlayerAlliance(sourcePlayer, otherPlayer, ALLIANCE_SHARED_CONTROL, flag)
4823 endfunction
4824
4825 //===========================================================================
4826 // Set all flags used by the in-game "Shared Units" checkbox with the Full
4827 // Shared Unit Control feature enabled.
4828 //
4829 function SetPlayerAllianceStateFullControlBJ takes player sourcePlayer, player otherPlayer, boolean flag returns nothing
4830 call SetPlayerAlliance(sourcePlayer, otherPlayer, ALLIANCE_SHARED_ADVANCED_CONTROL, flag)
4831 endfunction
4832
4833 //===========================================================================
4834 function SetPlayerAllianceStateBJ takes player sourcePlayer, player otherPlayer, integer allianceState returns nothing
4835 // Prevent players from attempting to ally with themselves.
4836 if (sourcePlayer == otherPlayer) then
4837 return
4838 endif
4839
4840 if allianceState == bj_ALLIANCE_UNALLIED then
4841 call SetPlayerAllianceStateAllyBJ( sourcePlayer, otherPlayer, false )
4842 call SetPlayerAllianceStateVisionBJ( sourcePlayer, otherPlayer, false )
4843 call SetPlayerAllianceStateControlBJ( sourcePlayer, otherPlayer, false )
4844 call SetPlayerAllianceStateFullControlBJ( sourcePlayer, otherPlayer, false )
4845 elseif allianceState == bj_ALLIANCE_UNALLIED_VISION then
4846 call SetPlayerAllianceStateAllyBJ( sourcePlayer, otherPlayer, false )
4847 call SetPlayerAllianceStateVisionBJ( sourcePlayer, otherPlayer, true )
4848 call SetPlayerAllianceStateControlBJ( sourcePlayer, otherPlayer, false )
4849 call SetPlayerAllianceStateFullControlBJ( sourcePlayer, otherPlayer, false )
4850 elseif allianceState == bj_ALLIANCE_ALLIED then
4851 call SetPlayerAllianceStateAllyBJ( sourcePlayer, otherPlayer, true )
4852 call SetPlayerAllianceStateVisionBJ( sourcePlayer, otherPlayer, false )
4853 call SetPlayerAllianceStateControlBJ( sourcePlayer, otherPlayer, false )
4854 call SetPlayerAllianceStateFullControlBJ( sourcePlayer, otherPlayer, false )
4855 elseif allianceState == bj_ALLIANCE_ALLIED_VISION then
4856 call SetPlayerAllianceStateAllyBJ( sourcePlayer, otherPlayer, true )
4857 call SetPlayerAllianceStateVisionBJ( sourcePlayer, otherPlayer, true )
4858 call SetPlayerAllianceStateControlBJ( sourcePlayer, otherPlayer, false )
4859 call SetPlayerAllianceStateFullControlBJ( sourcePlayer, otherPlayer, false )
4860 elseif allianceState == bj_ALLIANCE_ALLIED_UNITS then
4861 call SetPlayerAllianceStateAllyBJ( sourcePlayer, otherPlayer, true )
4862 call SetPlayerAllianceStateVisionBJ( sourcePlayer, otherPlayer, true )
4863 call SetPlayerAllianceStateControlBJ( sourcePlayer, otherPlayer, true )
4864 call SetPlayerAllianceStateFullControlBJ( sourcePlayer, otherPlayer, false )
4865 elseif allianceState == bj_ALLIANCE_ALLIED_ADVUNITS then
4866 call SetPlayerAllianceStateAllyBJ( sourcePlayer, otherPlayer, true )
4867 call SetPlayerAllianceStateVisionBJ( sourcePlayer, otherPlayer, true )
4868 call SetPlayerAllianceStateControlBJ( sourcePlayer, otherPlayer, true )
4869 call SetPlayerAllianceStateFullControlBJ( sourcePlayer, otherPlayer, true )
4870 elseif allianceState == bj_ALLIANCE_NEUTRAL then
4871 call SetPlayerAllianceStateAllyBJ( sourcePlayer, otherPlayer, false )
4872 call SetPlayerAllianceStateVisionBJ( sourcePlayer, otherPlayer, false )
4873 call SetPlayerAllianceStateControlBJ( sourcePlayer, otherPlayer, false )
4874 call SetPlayerAllianceStateFullControlBJ( sourcePlayer, otherPlayer, false )
4875 call SetPlayerAlliance( sourcePlayer, otherPlayer, ALLIANCE_PASSIVE, true )
4876 elseif allianceState == bj_ALLIANCE_NEUTRAL_VISION then
4877 call SetPlayerAllianceStateAllyBJ( sourcePlayer, otherPlayer, false )
4878 call SetPlayerAllianceStateVisionBJ( sourcePlayer, otherPlayer, true )
4879 call SetPlayerAllianceStateControlBJ( sourcePlayer, otherPlayer, false )
4880 call SetPlayerAllianceStateFullControlBJ( sourcePlayer, otherPlayer, false )
4881 call SetPlayerAlliance( sourcePlayer, otherPlayer, ALLIANCE_PASSIVE, true )
4882 else
4883 // Unrecognized alliance state - ignore the request.
4884 endif
4885 endfunction
4886
4887 //===========================================================================
4888 // Set the alliance states for an entire force towards another force.
4889 //
4890 function SetForceAllianceStateBJ takes force sourceForce, force targetForce, integer allianceState returns nothing
4891 local integer sourceIndex
4892 local integer targetIndex
4893
4894 set sourceIndex = 0
4895 loop
4896
4897 if (sourceForce==bj_FORCE_ALL_PLAYERS or IsPlayerInForce(Player(sourceIndex), sourceForce)) then
4898 set targetIndex = 0
4899 loop
4900 if (targetForce==bj_FORCE_ALL_PLAYERS or IsPlayerInForce(Player(targetIndex), targetForce)) then
4901 call SetPlayerAllianceStateBJ(Player(sourceIndex), Player(targetIndex), allianceState)
4902 endif
4903
4904 set targetIndex = targetIndex + 1
4905 exitwhen targetIndex == bj_MAX_PLAYER_SLOTS
4906 endloop
4907 endif
4908
4909 set sourceIndex = sourceIndex + 1
4910 exitwhen sourceIndex == bj_MAX_PLAYER_SLOTS
4911 endloop
4912 endfunction
4913
4914 //===========================================================================
4915 // Test to see if two players are co-allied (allied with each other).
4916 //
4917 function PlayersAreCoAllied takes player playerA, player playerB returns boolean
4918 // Players are considered to be allied with themselves.
4919 if (playerA == playerB) then
4920 return true
4921 endif
4922
4923 // Co-allies are both allied with each other.
4924 if GetPlayerAlliance(playerA, playerB, ALLIANCE_PASSIVE) then
4925 if GetPlayerAlliance(playerB, playerA, ALLIANCE_PASSIVE) then
4926 return true
4927 endif
4928 endif
4929 return false
4930 endfunction
4931
4932 //===========================================================================
4933 // Force (whichPlayer) AI player to share vision and advanced unit control
4934 // with all AI players of its allies.
4935 //
4936 function ShareEverythingWithTeamAI takes player whichPlayer returns nothing
4937 local integer playerIndex
4938 local player indexPlayer
4939
4940 set playerIndex = 0
4941 loop
4942 set indexPlayer = Player(playerIndex)
4943 if (PlayersAreCoAllied(whichPlayer, indexPlayer) and whichPlayer != indexPlayer) then
4944 if (GetPlayerController(indexPlayer) == MAP_CONTROL_COMPUTER) then
4945 call SetPlayerAlliance(whichPlayer, indexPlayer, ALLIANCE_SHARED_VISION, true)
4946 call SetPlayerAlliance(whichPlayer, indexPlayer, ALLIANCE_SHARED_CONTROL, true)
4947 call SetPlayerAlliance(whichPlayer, indexPlayer, ALLIANCE_SHARED_ADVANCED_CONTROL, true)
4948 endif
4949 endif
4950
4951 set playerIndex = playerIndex + 1
4952 exitwhen playerIndex == bj_MAX_PLAYERS
4953 endloop
4954 endfunction
4955
4956 //===========================================================================
4957 // Force (whichPlayer) to share vision and advanced unit control with all of his/her allies.
4958 //
4959 function ShareEverythingWithTeam takes player whichPlayer returns nothing
4960 local integer playerIndex
4961 local player indexPlayer
4962
4963 set playerIndex = 0
4964 loop
4965 set indexPlayer = Player(playerIndex)
4966 if (PlayersAreCoAllied(whichPlayer, indexPlayer) and whichPlayer != indexPlayer) then
4967 call SetPlayerAlliance(whichPlayer, indexPlayer, ALLIANCE_SHARED_VISION, true)
4968 call SetPlayerAlliance(whichPlayer, indexPlayer, ALLIANCE_SHARED_CONTROL, true)
4969 call SetPlayerAlliance(indexPlayer, whichPlayer, ALLIANCE_SHARED_CONTROL, true)
4970 call SetPlayerAlliance(whichPlayer, indexPlayer, ALLIANCE_SHARED_ADVANCED_CONTROL, true)
4971 endif
4972
4973 set playerIndex = playerIndex + 1
4974 exitwhen playerIndex == bj_MAX_PLAYERS
4975 endloop
4976 endfunction
4977
4978 //===========================================================================
4979 // Creates a 'Neutral Victim' player slot. This slot is passive towards all
4980 // other players, but all other players are aggressive towards him/her.
4981 //
4982 function ConfigureNeutralVictim takes nothing returns nothing
4983 local integer index
4984 local player indexPlayer
4985 local player neutralVictim = Player(bj_PLAYER_NEUTRAL_VICTIM)
4986
4987 set index = 0
4988 loop
4989 set indexPlayer = Player(index)
4990
4991 call SetPlayerAlliance(neutralVictim, indexPlayer, ALLIANCE_PASSIVE, true)
4992 call SetPlayerAlliance(indexPlayer, neutralVictim, ALLIANCE_PASSIVE, false)
4993
4994 set index = index + 1
4995 exitwhen index == bj_MAX_PLAYERS
4996 endloop
4997
4998 // Neutral Victim and Neutral Aggressive should not fight each other.
4999 set indexPlayer = Player(PLAYER_NEUTRAL_AGGRESSIVE)
5000 call SetPlayerAlliance(neutralVictim, indexPlayer, ALLIANCE_PASSIVE, true)
5001 call SetPlayerAlliance(indexPlayer, neutralVictim, ALLIANCE_PASSIVE, true)
5002
5003 // Neutral Victim does not give bounties.
5004 call SetPlayerState(neutralVictim, PLAYER_STATE_GIVES_BOUNTY, 0)
5005 endfunction
5006
5007 //===========================================================================
5008 function MakeUnitsPassiveForPlayerEnum takes nothing returns nothing
5009 call SetUnitOwner(GetEnumUnit(), Player(bj_PLAYER_NEUTRAL_VICTIM), false)
5010 endfunction
5011
5012 //===========================================================================
5013 // Change ownership for every unit of (whichPlayer)'s team to neutral passive.
5014 //
5015 function MakeUnitsPassiveForPlayer takes player whichPlayer returns nothing
5016 local group playerUnits = CreateGroup()
5017 call CachePlayerHeroData(whichPlayer)
5018 call GroupEnumUnitsOfPlayer(playerUnits, whichPlayer, null)
5019 call ForGroup(playerUnits, function MakeUnitsPassiveForPlayerEnum)
5020 call DestroyGroup(playerUnits)
5021 endfunction
5022
5023 //===========================================================================
5024 // Change ownership for every unit of (whichPlayer)'s team to neutral passive.
5025 //
5026 function MakeUnitsPassiveForTeam takes player whichPlayer returns nothing
5027 local integer playerIndex
5028 local player indexPlayer
5029
5030 set playerIndex = 0
5031 loop
5032 set indexPlayer = Player(playerIndex)
5033 if PlayersAreCoAllied(whichPlayer, indexPlayer) then
5034 call MakeUnitsPassiveForPlayer(indexPlayer)
5035 endif
5036
5037 set playerIndex = playerIndex + 1
5038 exitwhen playerIndex == bj_MAX_PLAYERS
5039 endloop
5040 endfunction
5041
5042 //===========================================================================
5043 // Determine whether or not victory/defeat is disabled via cheat codes.
5044 //
5045 function AllowVictoryDefeat takes playergameresult gameResult returns boolean
5046 if (gameResult == PLAYER_GAME_RESULT_VICTORY) then
5047 return not IsNoVictoryCheat()
5048 endif
5049 if (gameResult == PLAYER_GAME_RESULT_DEFEAT) then
5050 return not IsNoDefeatCheat()
5051 endif
5052 if (gameResult == PLAYER_GAME_RESULT_NEUTRAL) then
5053 return (not IsNoVictoryCheat()) and (not IsNoDefeatCheat())
5054 endif
5055 return true
5056 endfunction
5057
5058 //===========================================================================
5059 function EndGameBJ takes nothing returns nothing
5060 call EndGame( true )
5061 endfunction
5062
5063 //===========================================================================
5064 function MeleeVictoryDialogBJ takes player whichPlayer, boolean leftGame returns nothing
5065 local trigger t = CreateTrigger()
5066 local dialog d = DialogCreate()
5067 local string formatString
5068
5069 // Display "player was victorious" or "player has left the game" message
5070 if (leftGame) then
5071 set formatString = GetLocalizedString( "PLAYER_LEFT_GAME" )
5072 else
5073 set formatString = GetLocalizedString( "PLAYER_VICTORIOUS" )
5074 endif
5075
5076 call DisplayTimedTextFromPlayer(whichPlayer, 0, 0, 60, formatString)
5077
5078 call DialogSetMessage( d, GetLocalizedString( "GAMEOVER_VICTORY_MSG" ) )
5079 call DialogAddButton( d, GetLocalizedString( "GAMEOVER_CONTINUE_GAME" ), GetLocalizedHotkey("GAMEOVER_CONTINUE_GAME") )
5080
5081 set t = CreateTrigger()
5082 call TriggerRegisterDialogButtonEvent( t, DialogAddQuitButton( d, true, GetLocalizedString( "GAMEOVER_QUIT_GAME" ), GetLocalizedHotkey("GAMEOVER_QUIT_GAME") ) )
5083
5084 call DialogDisplay( whichPlayer, d, true )
5085 call StartSoundForPlayerBJ( whichPlayer, bj_victoryDialogSound )
5086 endfunction
5087
5088 //===========================================================================
5089 function MeleeDefeatDialogBJ takes player whichPlayer, boolean leftGame returns nothing
5090 local trigger t = CreateTrigger()
5091 local dialog d = DialogCreate()
5092 local string formatString
5093
5094 // Display "player was defeated" or "player has left the game" message
5095 if (leftGame) then
5096 set formatString = GetLocalizedString( "PLAYER_LEFT_GAME" )
5097 else
5098 set formatString = GetLocalizedString( "PLAYER_DEFEATED" )
5099 endif
5100
5101 call DisplayTimedTextFromPlayer(whichPlayer, 0, 0, 60, formatString)
5102
5103 call DialogSetMessage( d, GetLocalizedString( "GAMEOVER_DEFEAT_MSG" ) )
5104
5105 // Only show the continue button if the game is not over and observers on death are allowed
5106 if (not bj_meleeGameOver and IsMapFlagSet(MAP_OBSERVERS_ON_DEATH)) then
5107 call DialogAddButton( d, GetLocalizedString( "GAMEOVER_CONTINUE_OBSERVING" ), GetLocalizedHotkey("GAMEOVER_CONTINUE_OBSERVING") )
5108 endif
5109
5110 set t = CreateTrigger()
5111 call TriggerRegisterDialogButtonEvent( t, DialogAddQuitButton( d, true, GetLocalizedString( "GAMEOVER_QUIT_GAME" ), GetLocalizedHotkey("GAMEOVER_QUIT_GAME") ) )
5112
5113 call DialogDisplay( whichPlayer, d, true )
5114 call StartSoundForPlayerBJ( whichPlayer, bj_defeatDialogSound )
5115 endfunction
5116
5117 //===========================================================================
5118 function GameOverDialogBJ takes player whichPlayer, boolean leftGame returns nothing
5119 local trigger t = CreateTrigger()
5120 local dialog d = DialogCreate()
5121 local string s
5122
5123 // Display "player left the game" message
5124 call DisplayTimedTextFromPlayer(whichPlayer, 0, 0, 60, GetLocalizedString( "PLAYER_LEFT_GAME" ))
5125
5126 if (GetIntegerGameState(GAME_STATE_DISCONNECTED) != 0) then
5127 set s = GetLocalizedString( "GAMEOVER_DISCONNECTED" )
5128 else
5129 set s = GetLocalizedString( "GAMEOVER_GAME_OVER" )
5130 endif
5131
5132 call DialogSetMessage( d, s )
5133
5134 set t = CreateTrigger()
5135 call TriggerRegisterDialogButtonEvent( t, DialogAddQuitButton( d, true, GetLocalizedString( "GAMEOVER_OK" ), GetLocalizedHotkey("GAMEOVER_OK") ) )
5136
5137 call DialogDisplay( whichPlayer, d, true )
5138 call StartSoundForPlayerBJ( whichPlayer, bj_defeatDialogSound )
5139 endfunction
5140
5141 //===========================================================================
5142 function RemovePlayerPreserveUnitsBJ takes player whichPlayer, playergameresult gameResult, boolean leftGame returns nothing
5143 if AllowVictoryDefeat(gameResult) then
5144
5145 call RemovePlayer(whichPlayer, gameResult)
5146
5147 if( gameResult == PLAYER_GAME_RESULT_VICTORY ) then
5148 call MeleeVictoryDialogBJ( whichPlayer, leftGame )
5149 return
5150 elseif( gameResult == PLAYER_GAME_RESULT_DEFEAT ) then
5151 call MeleeDefeatDialogBJ( whichPlayer, leftGame )
5152 else
5153 call GameOverDialogBJ( whichPlayer, leftGame )
5154 endif
5155
5156 endif
5157 endfunction
5158
5159 //===========================================================================
5160 function CustomVictoryOkBJ takes nothing returns nothing
5161 if bj_isSinglePlayer then
5162 call PauseGame( false )
5163 // Bump the difficulty back up to the default.
5164 call SetGameDifficulty(GetDefaultDifficulty())
5165 endif
5166
5167 if (bj_changeLevelMapName == null) then
5168 call EndGame( bj_changeLevelShowScores )
5169 else
5170 call ChangeLevel( bj_changeLevelMapName, bj_changeLevelShowScores )
5171 endif
5172 endfunction
5173
5174 //===========================================================================
5175 function CustomVictoryQuitBJ takes nothing returns nothing
5176 if bj_isSinglePlayer then
5177 call PauseGame( false )
5178 // Bump the difficulty back up to the default.
5179 call SetGameDifficulty(GetDefaultDifficulty())
5180 endif
5181
5182 call EndGame( bj_changeLevelShowScores )
5183 endfunction
5184
5185 //===========================================================================
5186 function CustomVictoryDialogBJ takes player whichPlayer returns nothing
5187 local trigger t = CreateTrigger()
5188 local dialog d = DialogCreate()
5189
5190 call DialogSetMessage( d, GetLocalizedString( "GAMEOVER_VICTORY_MSG" ) )
5191
5192 set t = CreateTrigger()
5193 call TriggerRegisterDialogButtonEvent( t, DialogAddButton( d, GetLocalizedString( "GAMEOVER_CONTINUE" ), GetLocalizedHotkey("GAMEOVER_CONTINUE") ) )
5194 call TriggerAddAction( t, function CustomVictoryOkBJ )
5195
5196 set t = CreateTrigger()
5197 call TriggerRegisterDialogButtonEvent( t, DialogAddButton( d, GetLocalizedString( "GAMEOVER_QUIT_MISSION" ), GetLocalizedHotkey("GAMEOVER_QUIT_MISSION") ) )
5198 call TriggerAddAction( t, function CustomVictoryQuitBJ )
5199
5200 if (GetLocalPlayer() == whichPlayer) then
5201 call EnableUserControl( true )
5202 if bj_isSinglePlayer then
5203 call PauseGame( true )
5204 endif
5205 call EnableUserUI(false)
5206 endif
5207
5208 call DialogDisplay( whichPlayer, d, true )
5209 call VolumeGroupSetVolumeForPlayerBJ( whichPlayer, SOUND_VOLUMEGROUP_UI, 1.0 )
5210 call StartSoundForPlayerBJ( whichPlayer, bj_victoryDialogSound )
5211 endfunction
5212
5213 //===========================================================================
5214 function CustomVictorySkipBJ takes player whichPlayer returns nothing
5215 if (GetLocalPlayer() == whichPlayer) then
5216 if bj_isSinglePlayer then
5217 // Bump the difficulty back up to the default.
5218 call SetGameDifficulty(GetDefaultDifficulty())
5219 endif
5220
5221 if (bj_changeLevelMapName == null) then
5222 call EndGame( bj_changeLevelShowScores )
5223 else
5224 call ChangeLevel( bj_changeLevelMapName, bj_changeLevelShowScores )
5225 endif
5226 endif
5227 endfunction
5228
5229 //===========================================================================
5230 function CustomVictoryBJ takes player whichPlayer, boolean showDialog, boolean showScores returns nothing
5231 if AllowVictoryDefeat( PLAYER_GAME_RESULT_VICTORY ) then
5232 call RemovePlayer( whichPlayer, PLAYER_GAME_RESULT_VICTORY )
5233
5234 if not bj_isSinglePlayer then
5235 call DisplayTimedTextFromPlayer(whichPlayer, 0, 0, 60, GetLocalizedString( "PLAYER_VICTORIOUS" ) )
5236 endif
5237
5238 // UI only needs to be displayed to users.
5239 if (GetPlayerController(whichPlayer) == MAP_CONTROL_USER) then
5240 set bj_changeLevelShowScores = showScores
5241 if showDialog then
5242 call CustomVictoryDialogBJ( whichPlayer )
5243 else
5244 call CustomVictorySkipBJ( whichPlayer )
5245 endif
5246 endif
5247 endif
5248 endfunction
5249
5250 //===========================================================================
5251 function CustomDefeatRestartBJ takes nothing returns nothing
5252 call PauseGame( false )
5253 call RestartGame( true )
5254 endfunction
5255
5256 //===========================================================================
5257 function CustomDefeatReduceDifficultyBJ takes nothing returns nothing
5258 local gamedifficulty diff = GetGameDifficulty()
5259
5260 call PauseGame( false )
5261
5262 // Knock the difficulty down, if possible.
5263 if (diff == MAP_DIFFICULTY_EASY) then
5264 // Sorry, but it doesn't get any easier than this.
5265 elseif (diff == MAP_DIFFICULTY_NORMAL) then
5266 call SetGameDifficulty(MAP_DIFFICULTY_EASY)
5267 elseif (diff == MAP_DIFFICULTY_HARD) then
5268 call SetGameDifficulty(MAP_DIFFICULTY_NORMAL)
5269 else
5270 // Unrecognized difficulty
5271 endif
5272
5273 call RestartGame( true )
5274 endfunction
5275
5276 //===========================================================================
5277 function CustomDefeatLoadBJ takes nothing returns nothing
5278 call PauseGame( false )
5279 call DisplayLoadDialog()
5280 endfunction
5281
5282 //===========================================================================
5283 function CustomDefeatQuitBJ takes nothing returns nothing
5284 if bj_isSinglePlayer then
5285 call PauseGame( false )
5286 endif
5287
5288 // Bump the difficulty back up to the default.
5289 call SetGameDifficulty(GetDefaultDifficulty())
5290 call EndGame( true )
5291 endfunction
5292
5293 //===========================================================================
5294 function CustomDefeatDialogBJ takes player whichPlayer, string message returns nothing
5295 local trigger t = CreateTrigger()
5296 local dialog d = DialogCreate()
5297
5298 call DialogSetMessage( d, message )
5299
5300 if bj_isSinglePlayer then
5301 set t = CreateTrigger()
5302 call TriggerRegisterDialogButtonEvent( t, DialogAddButton( d, GetLocalizedString( "GAMEOVER_RESTART" ), GetLocalizedHotkey("GAMEOVER_RESTART") ) )
5303 call TriggerAddAction( t, function CustomDefeatRestartBJ )
5304
5305 if (GetGameDifficulty() != MAP_DIFFICULTY_EASY) then
5306 set t = CreateTrigger()
5307 call TriggerRegisterDialogButtonEvent( t, DialogAddButton( d, GetLocalizedString( "GAMEOVER_REDUCE_DIFFICULTY" ), GetLocalizedHotkey("GAMEOVER_REDUCE_DIFFICULTY") ) )
5308 call TriggerAddAction( t, function CustomDefeatReduceDifficultyBJ )
5309 endif
5310
5311 set t = CreateTrigger()
5312 call TriggerRegisterDialogButtonEvent( t, DialogAddButton( d, GetLocalizedString( "GAMEOVER_LOAD" ), GetLocalizedHotkey("GAMEOVER_LOAD") ) )
5313 call TriggerAddAction( t, function CustomDefeatLoadBJ )
5314 endif
5315
5316 set t = CreateTrigger()
5317 call TriggerRegisterDialogButtonEvent( t, DialogAddButton( d, GetLocalizedString( "GAMEOVER_QUIT_MISSION" ), GetLocalizedHotkey("GAMEOVER_QUIT_MISSION") ) )
5318 call TriggerAddAction( t, function CustomDefeatQuitBJ )
5319
5320 if (GetLocalPlayer() == whichPlayer) then
5321 call EnableUserControl( true )
5322 if bj_isSinglePlayer then
5323 call PauseGame( true )
5324 endif
5325 call EnableUserUI(false)
5326 endif
5327
5328 call DialogDisplay( whichPlayer, d, true )
5329 call VolumeGroupSetVolumeForPlayerBJ( whichPlayer, SOUND_VOLUMEGROUP_UI, 1.0 )
5330 call StartSoundForPlayerBJ( whichPlayer, bj_defeatDialogSound )
5331 endfunction
5332
5333 //===========================================================================
5334 function CustomDefeatBJ takes player whichPlayer, string message returns nothing
5335 if AllowVictoryDefeat( PLAYER_GAME_RESULT_DEFEAT ) then
5336 call RemovePlayer( whichPlayer, PLAYER_GAME_RESULT_DEFEAT )
5337
5338 if not bj_isSinglePlayer then
5339 call DisplayTimedTextFromPlayer(whichPlayer, 0, 0, 60, GetLocalizedString( "PLAYER_DEFEATED" ) )
5340 endif
5341
5342 // UI only needs to be displayed to users.
5343 if (GetPlayerController(whichPlayer) == MAP_CONTROL_USER) then
5344 call CustomDefeatDialogBJ( whichPlayer, message )
5345 endif
5346 endif
5347 endfunction
5348
5349 //===========================================================================
5350 function SetNextLevelBJ takes string nextLevel returns nothing
5351 if (nextLevel == "") then
5352 set bj_changeLevelMapName = null
5353 else
5354 set bj_changeLevelMapName = nextLevel
5355 endif
5356 endfunction
5357
5358 //===========================================================================
5359 function SetPlayerOnScoreScreenBJ takes boolean flag, player whichPlayer returns nothing
5360 call SetPlayerOnScoreScreen(whichPlayer, flag)
5361 endfunction
5362
5363
5364
5365 //***************************************************************************
5366 //*
5367 //* Quest Utility Functions
5368 //*
5369 //***************************************************************************
5370
5371 //===========================================================================
5372 function CreateQuestBJ takes integer questType, string title, string description, string iconPath returns quest
5373 local boolean required = (questType == bj_QUESTTYPE_REQ_DISCOVERED) or (questType == bj_QUESTTYPE_REQ_UNDISCOVERED)
5374 local boolean discovered = (questType == bj_QUESTTYPE_REQ_DISCOVERED) or (questType == bj_QUESTTYPE_OPT_DISCOVERED)
5375
5376 set bj_lastCreatedQuest = CreateQuest()
5377 call QuestSetTitle(bj_lastCreatedQuest, title)
5378 call QuestSetDescription(bj_lastCreatedQuest, description)
5379 call QuestSetIconPath(bj_lastCreatedQuest, iconPath)
5380 call QuestSetRequired(bj_lastCreatedQuest, required)
5381 call QuestSetDiscovered(bj_lastCreatedQuest, discovered)
5382 call QuestSetCompleted(bj_lastCreatedQuest, false)
5383 return bj_lastCreatedQuest
5384 endfunction
5385
5386 //===========================================================================
5387 function DestroyQuestBJ takes quest whichQuest returns nothing
5388 call DestroyQuest(whichQuest)
5389 endfunction
5390
5391 //===========================================================================
5392 function QuestSetEnabledBJ takes boolean enabled, quest whichQuest returns nothing
5393 call QuestSetEnabled(whichQuest, enabled)
5394 endfunction
5395
5396 //===========================================================================
5397 function QuestSetTitleBJ takes quest whichQuest, string title returns nothing
5398 call QuestSetTitle(whichQuest, title)
5399 endfunction
5400
5401 //===========================================================================
5402 function QuestSetDescriptionBJ takes quest whichQuest, string description returns nothing
5403 call QuestSetDescription(whichQuest, description)
5404 endfunction
5405
5406 //===========================================================================
5407 function QuestSetCompletedBJ takes quest whichQuest, boolean completed returns nothing
5408 call QuestSetCompleted(whichQuest, completed)
5409 endfunction
5410
5411 //===========================================================================
5412 function QuestSetFailedBJ takes quest whichQuest, boolean failed returns nothing
5413 call QuestSetFailed(whichQuest, failed)
5414 endfunction
5415
5416 //===========================================================================
5417 function QuestSetDiscoveredBJ takes quest whichQuest, boolean discovered returns nothing
5418 call QuestSetDiscovered(whichQuest, discovered)
5419 endfunction
5420
5421 //===========================================================================
5422 function GetLastCreatedQuestBJ takes nothing returns quest
5423 return bj_lastCreatedQuest
5424 endfunction
5425
5426 //===========================================================================
5427 function CreateQuestItemBJ takes quest whichQuest, string description returns questitem
5428 set bj_lastCreatedQuestItem = QuestCreateItem(whichQuest)
5429 call QuestItemSetDescription(bj_lastCreatedQuestItem, description)
5430 call QuestItemSetCompleted(bj_lastCreatedQuestItem, false)
5431 return bj_lastCreatedQuestItem
5432 endfunction
5433
5434 //===========================================================================
5435 function QuestItemSetDescriptionBJ takes questitem whichQuestItem, string description returns nothing
5436 call QuestItemSetDescription(whichQuestItem, description)
5437 endfunction
5438
5439 //===========================================================================
5440 function QuestItemSetCompletedBJ takes questitem whichQuestItem, boolean completed returns nothing
5441 call QuestItemSetCompleted(whichQuestItem, completed)
5442 endfunction
5443
5444 //===========================================================================
5445 function GetLastCreatedQuestItemBJ takes nothing returns questitem
5446 return bj_lastCreatedQuestItem
5447 endfunction
5448
5449 //===========================================================================
5450 function CreateDefeatConditionBJ takes string description returns defeatcondition
5451 set bj_lastCreatedDefeatCondition = CreateDefeatCondition()
5452 call DefeatConditionSetDescription(bj_lastCreatedDefeatCondition, description)
5453 return bj_lastCreatedDefeatCondition
5454 endfunction
5455
5456 //===========================================================================
5457 function DestroyDefeatConditionBJ takes defeatcondition whichCondition returns nothing
5458 call DestroyDefeatCondition(whichCondition)
5459 endfunction
5460
5461 //===========================================================================
5462 function DefeatConditionSetDescriptionBJ takes defeatcondition whichCondition, string description returns nothing
5463 call DefeatConditionSetDescription(whichCondition, description)
5464 endfunction
5465
5466 //===========================================================================
5467 function GetLastCreatedDefeatConditionBJ takes nothing returns defeatcondition
5468 return bj_lastCreatedDefeatCondition
5469 endfunction
5470
5471 //===========================================================================
5472 function FlashQuestDialogButtonBJ takes nothing returns nothing
5473 call FlashQuestDialogButton()
5474 endfunction
5475
5476 //===========================================================================
5477 function QuestMessageBJ takes force f, integer messageType, string message returns nothing
5478 if (IsPlayerInForce(GetLocalPlayer(), f)) then
5479 // Use only local code (no net traffic) within this block to avoid desyncs.
5480
5481 if (messageType == bj_QUESTMESSAGE_DISCOVERED) then
5482 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_TEXT_DELAY_QUEST, " ")
5483 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_TEXT_DELAY_QUEST, message)
5484 call StartSound(bj_questDiscoveredSound)
5485 call FlashQuestDialogButton()
5486
5487 elseif (messageType == bj_QUESTMESSAGE_UPDATED) then
5488 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_TEXT_DELAY_QUESTUPDATE, " ")
5489 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_TEXT_DELAY_QUESTUPDATE, message)
5490 call StartSound(bj_questUpdatedSound)
5491 call FlashQuestDialogButton()
5492
5493 elseif (messageType == bj_QUESTMESSAGE_COMPLETED) then
5494 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_TEXT_DELAY_QUESTDONE, " ")
5495 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_TEXT_DELAY_QUESTDONE, message)
5496 call StartSound(bj_questCompletedSound)
5497 call FlashQuestDialogButton()
5498
5499 elseif (messageType == bj_QUESTMESSAGE_FAILED) then
5500 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_TEXT_DELAY_QUESTFAILED, " ")
5501 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_TEXT_DELAY_QUESTFAILED, message)
5502 call StartSound(bj_questFailedSound)
5503 call FlashQuestDialogButton()
5504
5505 elseif (messageType == bj_QUESTMESSAGE_REQUIREMENT) then
5506 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_TEXT_DELAY_QUESTREQUIREMENT, message)
5507
5508 elseif (messageType == bj_QUESTMESSAGE_MISSIONFAILED) then
5509 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_TEXT_DELAY_MISSIONFAILED, " ")
5510 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_TEXT_DELAY_MISSIONFAILED, message)
5511 call StartSound(bj_questFailedSound)
5512
5513 elseif (messageType == bj_QUESTMESSAGE_HINT) then
5514 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_TEXT_DELAY_HINT, " ")
5515 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_TEXT_DELAY_HINT, message)
5516 call StartSound(bj_questHintSound)
5517
5518 elseif (messageType == bj_QUESTMESSAGE_ALWAYSHINT) then
5519 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_TEXT_DELAY_ALWAYSHINT, " ")
5520 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_TEXT_DELAY_ALWAYSHINT, message)
5521 call StartSound(bj_questHintSound)
5522
5523 elseif (messageType == bj_QUESTMESSAGE_SECRET) then
5524 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_TEXT_DELAY_SECRET, " ")
5525 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_TEXT_DELAY_SECRET, message)
5526 call StartSound(bj_questSecretSound)
5527
5528 elseif (messageType == bj_QUESTMESSAGE_UNITACQUIRED) then
5529 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_TEXT_DELAY_UNITACQUIRED, " ")
5530 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_TEXT_DELAY_UNITACQUIRED, message)
5531 call StartSound(bj_questHintSound)
5532
5533 elseif (messageType == bj_QUESTMESSAGE_UNITAVAILABLE) then
5534 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_TEXT_DELAY_UNITAVAILABLE, " ")
5535 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_TEXT_DELAY_UNITAVAILABLE, message)
5536 call StartSound(bj_questHintSound)
5537
5538 elseif (messageType == bj_QUESTMESSAGE_ITEMACQUIRED) then
5539 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_TEXT_DELAY_ITEMACQUIRED, " ")
5540 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_TEXT_DELAY_ITEMACQUIRED, message)
5541 call StartSound(bj_questItemAcquiredSound)
5542
5543 elseif (messageType == bj_QUESTMESSAGE_WARNING) then
5544 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_TEXT_DELAY_WARNING, " ")
5545 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_TEXT_DELAY_WARNING, message)
5546 call StartSound(bj_questWarningSound)
5547
5548 else
5549 // Unrecognized message type - ignore the request.
5550 endif
5551 endif
5552 endfunction
5553
5554
5555
5556 //***************************************************************************
5557 //*
5558 //* Timer Utility Functions
5559 //*
5560 //***************************************************************************
5561
5562 //===========================================================================
5563 function StartTimerBJ takes timer t, boolean periodic, real timeout returns timer
5564 set bj_lastStartedTimer = t
5565 call TimerStart(t, timeout, periodic, null)
5566 return bj_lastStartedTimer
5567 endfunction
5568
5569 //===========================================================================
5570 function CreateTimerBJ takes boolean periodic, real timeout returns timer
5571 set bj_lastStartedTimer = CreateTimer()
5572 call TimerStart(bj_lastStartedTimer, timeout, periodic, null)
5573 return bj_lastStartedTimer
5574 endfunction
5575
5576 //===========================================================================
5577 function DestroyTimerBJ takes timer whichTimer returns nothing
5578 call DestroyTimer(whichTimer)
5579 endfunction
5580
5581 //===========================================================================
5582 function PauseTimerBJ takes boolean pause, timer whichTimer returns nothing
5583 if pause then
5584 call PauseTimer(whichTimer)
5585 else
5586 call ResumeTimer(whichTimer)
5587 endif
5588 endfunction
5589
5590 //===========================================================================
5591 function GetLastCreatedTimerBJ takes nothing returns timer
5592 return bj_lastStartedTimer
5593 endfunction
5594
5595 //===========================================================================
5596 function CreateTimerDialogBJ takes timer t, string title returns timerdialog
5597 set bj_lastCreatedTimerDialog = CreateTimerDialog(t)
5598 call TimerDialogSetTitle(bj_lastCreatedTimerDialog, title)
5599 call TimerDialogDisplay(bj_lastCreatedTimerDialog, true)
5600 return bj_lastCreatedTimerDialog
5601 endfunction
5602
5603 //===========================================================================
5604 function DestroyTimerDialogBJ takes timerdialog td returns nothing
5605 call DestroyTimerDialog(td)
5606 endfunction
5607
5608 //===========================================================================
5609 function TimerDialogSetTitleBJ takes timerdialog td, string title returns nothing
5610 call TimerDialogSetTitle(td, title)
5611 endfunction
5612
5613 //===========================================================================
5614 function TimerDialogSetTitleColorBJ takes timerdialog td, real red, real green, real blue, real transparency returns nothing
5615 call TimerDialogSetTitleColor(td, PercentTo255(red), PercentTo255(green), PercentTo255(blue), PercentTo255(100.0-transparency))
5616 endfunction
5617
5618 //===========================================================================
5619 function TimerDialogSetTimeColorBJ takes timerdialog td, real red, real green, real blue, real transparency returns nothing
5620 call TimerDialogSetTimeColor(td, PercentTo255(red), PercentTo255(green), PercentTo255(blue), PercentTo255(100.0-transparency))
5621 endfunction
5622
5623 //===========================================================================
5624 function TimerDialogSetSpeedBJ takes timerdialog td, real speedMultFactor returns nothing
5625 call TimerDialogSetSpeed(td, speedMultFactor)
5626 endfunction
5627
5628 //===========================================================================
5629 function TimerDialogDisplayForPlayerBJ takes boolean show, timerdialog td, player whichPlayer returns nothing
5630 if (GetLocalPlayer() == whichPlayer) then
5631 // Use only local code (no net traffic) within this block to avoid desyncs.
5632 call TimerDialogDisplay(td, show)
5633 endif
5634 endfunction
5635
5636 //===========================================================================
5637 function TimerDialogDisplayBJ takes boolean show, timerdialog td returns nothing
5638 call TimerDialogDisplay(td, show)
5639 endfunction
5640
5641 //===========================================================================
5642 function GetLastCreatedTimerDialogBJ takes nothing returns timerdialog
5643 return bj_lastCreatedTimerDialog
5644 endfunction
5645
5646
5647
5648 //***************************************************************************
5649 //*
5650 //* Leaderboard Utility Functions
5651 //*
5652 //***************************************************************************
5653
5654 //===========================================================================
5655 function LeaderboardResizeBJ takes leaderboard lb returns nothing
5656 local integer size = LeaderboardGetItemCount(lb)
5657
5658 if (LeaderboardGetLabelText(lb) == "") then
5659 set size = size - 1
5660 endif
5661 call LeaderboardSetSizeByItemCount(lb, size)
5662 endfunction
5663
5664 //===========================================================================
5665 function LeaderboardSetPlayerItemValueBJ takes player whichPlayer, leaderboard lb, integer val returns nothing
5666 call LeaderboardSetItemValue(lb, LeaderboardGetPlayerIndex(lb, whichPlayer), val)
5667 endfunction
5668
5669 //===========================================================================
5670 function LeaderboardSetPlayerItemLabelBJ takes player whichPlayer, leaderboard lb, string val returns nothing
5671 call LeaderboardSetItemLabel(lb, LeaderboardGetPlayerIndex(lb, whichPlayer), val)
5672 endfunction
5673
5674 //===========================================================================
5675 function LeaderboardSetPlayerItemStyleBJ takes player whichPlayer, leaderboard lb, boolean showLabel, boolean showValue, boolean showIcon returns nothing
5676 call LeaderboardSetItemStyle(lb, LeaderboardGetPlayerIndex(lb, whichPlayer), showLabel, showValue, showIcon)
5677 endfunction
5678
5679 //===========================================================================
5680 function LeaderboardSetPlayerItemLabelColorBJ takes player whichPlayer, leaderboard lb, real red, real green, real blue, real transparency returns nothing
5681 call LeaderboardSetItemLabelColor(lb, LeaderboardGetPlayerIndex(lb, whichPlayer), PercentTo255(red), PercentTo255(green), PercentTo255(blue), PercentTo255(100.0-transparency))
5682 endfunction
5683
5684 //===========================================================================
5685 function LeaderboardSetPlayerItemValueColorBJ takes player whichPlayer, leaderboard lb, real red, real green, real blue, real transparency returns nothing
5686 call LeaderboardSetItemValueColor(lb, LeaderboardGetPlayerIndex(lb, whichPlayer), PercentTo255(red), PercentTo255(green), PercentTo255(blue), PercentTo255(100.0-transparency))
5687 endfunction
5688
5689 //===========================================================================
5690 function LeaderboardSetLabelColorBJ takes leaderboard lb, real red, real green, real blue, real transparency returns nothing
5691 call LeaderboardSetLabelColor(lb, PercentTo255(red), PercentTo255(green), PercentTo255(blue), PercentTo255(100.0-transparency))
5692 endfunction
5693
5694 //===========================================================================
5695 function LeaderboardSetValueColorBJ takes leaderboard lb, real red, real green, real blue, real transparency returns nothing
5696 call LeaderboardSetValueColor(lb, PercentTo255(red), PercentTo255(green), PercentTo255(blue), PercentTo255(100.0-transparency))
5697 endfunction
5698
5699 //===========================================================================
5700 function LeaderboardSetLabelBJ takes leaderboard lb, string label returns nothing
5701 call LeaderboardSetLabel(lb, label)
5702 call LeaderboardResizeBJ(lb)
5703 endfunction
5704
5705 //===========================================================================
5706 function LeaderboardSetStyleBJ takes leaderboard lb, boolean showLabel, boolean showNames, boolean showValues, boolean showIcons returns nothing
5707 call LeaderboardSetStyle(lb, showLabel, showNames, showValues, showIcons)
5708 endfunction
5709
5710 //===========================================================================
5711 function LeaderboardGetItemCountBJ takes leaderboard lb returns integer
5712 return LeaderboardGetItemCount(lb)
5713 endfunction
5714
5715 //===========================================================================
5716 function LeaderboardHasPlayerItemBJ takes leaderboard lb, player whichPlayer returns boolean
5717 return LeaderboardHasPlayerItem(lb, whichPlayer)
5718 endfunction
5719
5720 //===========================================================================
5721 function ForceSetLeaderboardBJ takes leaderboard lb, force toForce returns nothing
5722 local integer index
5723 local player indexPlayer
5724
5725 set index = 0
5726 loop
5727 set indexPlayer = Player(index)
5728 if IsPlayerInForce(indexPlayer, toForce) then
5729 call PlayerSetLeaderboard(indexPlayer, lb)
5730 endif
5731 set index = index + 1
5732 exitwhen index == bj_MAX_PLAYERS
5733 endloop
5734 endfunction
5735
5736 //===========================================================================
5737 function CreateLeaderboardBJ takes force toForce, string label returns leaderboard
5738 set bj_lastCreatedLeaderboard = CreateLeaderboard()
5739 call LeaderboardSetLabel(bj_lastCreatedLeaderboard, label)
5740 call ForceSetLeaderboardBJ(bj_lastCreatedLeaderboard, toForce)
5741 call LeaderboardDisplay(bj_lastCreatedLeaderboard, true)
5742 return bj_lastCreatedLeaderboard
5743 endfunction
5744
5745 //===========================================================================
5746 function DestroyLeaderboardBJ takes leaderboard lb returns nothing
5747 call DestroyLeaderboard(lb)
5748 endfunction
5749
5750 //===========================================================================
5751 function LeaderboardDisplayBJ takes boolean show, leaderboard lb returns nothing
5752 call LeaderboardDisplay(lb, show)
5753 endfunction
5754
5755 //===========================================================================
5756 function LeaderboardAddItemBJ takes player whichPlayer, leaderboard lb, string label, integer value returns nothing
5757 if (LeaderboardHasPlayerItem(lb, whichPlayer)) then
5758 call LeaderboardRemovePlayerItem(lb, whichPlayer)
5759 endif
5760 call LeaderboardAddItem(lb, label, value, whichPlayer)
5761 call LeaderboardResizeBJ(lb)
5762 //call LeaderboardSetSizeByItemCount(lb, LeaderboardGetItemCount(lb))
5763 endfunction
5764
5765 //===========================================================================
5766 function LeaderboardRemovePlayerItemBJ takes player whichPlayer, leaderboard lb returns nothing
5767 call LeaderboardRemovePlayerItem(lb, whichPlayer)
5768 call LeaderboardResizeBJ(lb)
5769 endfunction
5770
5771 //===========================================================================
5772 function LeaderboardSortItemsBJ takes leaderboard lb, integer sortType, boolean ascending returns nothing
5773 if (sortType == bj_SORTTYPE_SORTBYVALUE) then
5774 call LeaderboardSortItemsByValue(lb, ascending)
5775 elseif (sortType == bj_SORTTYPE_SORTBYPLAYER) then
5776 call LeaderboardSortItemsByPlayer(lb, ascending)
5777 elseif (sortType == bj_SORTTYPE_SORTBYLABEL) then
5778 call LeaderboardSortItemsByLabel(lb, ascending)
5779 else
5780 // Unrecognized sort type - ignore the request.
5781 endif
5782 endfunction
5783
5784 //===========================================================================
5785 function LeaderboardSortItemsByPlayerBJ takes leaderboard lb, boolean ascending returns nothing
5786 call LeaderboardSortItemsByPlayer(lb, ascending)
5787 endfunction
5788
5789 //===========================================================================
5790 function LeaderboardSortItemsByLabelBJ takes leaderboard lb, boolean ascending returns nothing
5791 call LeaderboardSortItemsByLabel(lb, ascending)
5792 endfunction
5793
5794 //===========================================================================
5795 function LeaderboardGetPlayerIndexBJ takes player whichPlayer, leaderboard lb returns integer
5796 return LeaderboardGetPlayerIndex(lb, whichPlayer) + 1
5797 endfunction
5798
5799 //===========================================================================
5800 // Returns the player who is occupying a specified position in a leaderboard.
5801 // The position parameter is expected in the range of 1..16.
5802 //
5803 function LeaderboardGetIndexedPlayerBJ takes integer position, leaderboard lb returns player
5804 local integer index
5805 local player indexPlayer
5806
5807 set index = 0
5808 loop
5809 set indexPlayer = Player(index)
5810 if (LeaderboardGetPlayerIndex(lb, indexPlayer) == position - 1) then
5811 return indexPlayer
5812 endif
5813
5814 set index = index + 1
5815 exitwhen index == bj_MAX_PLAYERS
5816 endloop
5817
5818 return Player(PLAYER_NEUTRAL_PASSIVE)
5819 endfunction
5820
5821 //===========================================================================
5822 function PlayerGetLeaderboardBJ takes player whichPlayer returns leaderboard
5823 return PlayerGetLeaderboard(whichPlayer)
5824 endfunction
5825
5826 //===========================================================================
5827 function GetLastCreatedLeaderboard takes nothing returns leaderboard
5828 return bj_lastCreatedLeaderboard
5829 endfunction
5830
5831 //***************************************************************************
5832 //*
5833 //* Multiboard Utility Functions
5834 //*
5835 //***************************************************************************
5836
5837 //===========================================================================
5838 function CreateMultiboardBJ takes integer cols, integer rows, string title returns multiboard
5839 set bj_lastCreatedMultiboard = CreateMultiboard()
5840 call MultiboardSetRowCount(bj_lastCreatedMultiboard, rows)
5841 call MultiboardSetColumnCount(bj_lastCreatedMultiboard, cols)
5842 call MultiboardSetTitleText(bj_lastCreatedMultiboard, title)
5843 call MultiboardDisplay(bj_lastCreatedMultiboard, true)
5844 return bj_lastCreatedMultiboard
5845 endfunction
5846
5847 //===========================================================================
5848 function DestroyMultiboardBJ takes multiboard mb returns nothing
5849 call DestroyMultiboard(mb)
5850 endfunction
5851
5852 //===========================================================================
5853 function GetLastCreatedMultiboard takes nothing returns multiboard
5854 return bj_lastCreatedMultiboard
5855 endfunction
5856
5857 //===========================================================================
5858 function MultiboardDisplayBJ takes boolean show, multiboard mb returns nothing
5859 call MultiboardDisplay(mb, show)
5860 endfunction
5861
5862 //===========================================================================
5863 function MultiboardMinimizeBJ takes boolean minimize, multiboard mb returns nothing
5864 call MultiboardMinimize(mb, minimize)
5865 endfunction
5866
5867 //===========================================================================
5868 function MultiboardSetTitleTextColorBJ takes multiboard mb, real red, real green, real blue, real transparency returns nothing
5869 call MultiboardSetTitleTextColor(mb, PercentTo255(red), PercentTo255(green), PercentTo255(blue), PercentTo255(100.0-transparency))
5870 endfunction
5871
5872 //===========================================================================
5873 function MultiboardAllowDisplayBJ takes boolean flag returns nothing
5874 call MultiboardSuppressDisplay(not flag)
5875 endfunction
5876
5877 //===========================================================================
5878 function MultiboardSetItemStyleBJ takes multiboard mb, integer col, integer row, boolean showValue, boolean showIcon returns nothing
5879 local integer curRow = 0
5880 local integer curCol = 0
5881 local integer numRows = MultiboardGetRowCount(mb)
5882 local integer numCols = MultiboardGetColumnCount(mb)
5883 local multiboarditem mbitem = null
5884
5885 // Loop over rows, using 1-based index
5886 loop
5887 set curRow = curRow + 1
5888 exitwhen curRow > numRows
5889
5890 // Apply setting to the requested row, or all rows (if row is 0)
5891 if (row == 0 or row == curRow) then
5892 // Loop over columns, using 1-based index
5893 set curCol = 0
5894 loop
5895 set curCol = curCol + 1
5896 exitwhen curCol > numCols
5897
5898 // Apply setting to the requested column, or all columns (if col is 0)
5899 if (col == 0 or col == curCol) then
5900 set mbitem = MultiboardGetItem(mb, curRow - 1, curCol - 1)
5901 call MultiboardSetItemStyle(mbitem, showValue, showIcon)
5902 call MultiboardReleaseItem(mbitem)
5903 endif
5904 endloop
5905 endif
5906 endloop
5907 endfunction
5908
5909 //===========================================================================
5910 function MultiboardSetItemValueBJ takes multiboard mb, integer col, integer row, string val returns nothing
5911 local integer curRow = 0
5912 local integer curCol = 0
5913 local integer numRows = MultiboardGetRowCount(mb)
5914 local integer numCols = MultiboardGetColumnCount(mb)
5915 local multiboarditem mbitem = null
5916
5917 // Loop over rows, using 1-based index
5918 loop
5919 set curRow = curRow + 1
5920 exitwhen curRow > numRows
5921
5922 // Apply setting to the requested row, or all rows (if row is 0)
5923 if (row == 0 or row == curRow) then
5924 // Loop over columns, using 1-based index
5925 set curCol = 0
5926 loop
5927 set curCol = curCol + 1
5928 exitwhen curCol > numCols
5929
5930 // Apply setting to the requested column, or all columns (if col is 0)
5931 if (col == 0 or col == curCol) then
5932 set mbitem = MultiboardGetItem(mb, curRow - 1, curCol - 1)
5933 call MultiboardSetItemValue(mbitem, val)
5934 call MultiboardReleaseItem(mbitem)
5935 endif
5936 endloop
5937 endif
5938 endloop
5939 endfunction
5940
5941 //===========================================================================
5942 function MultiboardSetItemColorBJ takes multiboard mb, integer col, integer row, real red, real green, real blue, real transparency returns nothing
5943 local integer curRow = 0
5944 local integer curCol = 0
5945 local integer numRows = MultiboardGetRowCount(mb)
5946 local integer numCols = MultiboardGetColumnCount(mb)
5947 local multiboarditem mbitem = null
5948
5949 // Loop over rows, using 1-based index
5950 loop
5951 set curRow = curRow + 1
5952 exitwhen curRow > numRows
5953
5954 // Apply setting to the requested row, or all rows (if row is 0)
5955 if (row == 0 or row == curRow) then
5956 // Loop over columns, using 1-based index
5957 set curCol = 0
5958 loop
5959 set curCol = curCol + 1
5960 exitwhen curCol > numCols
5961
5962 // Apply setting to the requested column, or all columns (if col is 0)
5963 if (col == 0 or col == curCol) then
5964 set mbitem = MultiboardGetItem(mb, curRow - 1, curCol - 1)
5965 call MultiboardSetItemValueColor(mbitem, PercentTo255(red), PercentTo255(green), PercentTo255(blue), PercentTo255(100.0-transparency))
5966 call MultiboardReleaseItem(mbitem)
5967 endif
5968 endloop
5969 endif
5970 endloop
5971 endfunction
5972
5973 //===========================================================================
5974 function MultiboardSetItemWidthBJ takes multiboard mb, integer col, integer row, real width returns nothing
5975 local integer curRow = 0
5976 local integer curCol = 0
5977 local integer numRows = MultiboardGetRowCount(mb)
5978 local integer numCols = MultiboardGetColumnCount(mb)
5979 local multiboarditem mbitem = null
5980
5981 // Loop over rows, using 1-based index
5982 loop
5983 set curRow = curRow + 1
5984 exitwhen curRow > numRows
5985
5986 // Apply setting to the requested row, or all rows (if row is 0)
5987 if (row == 0 or row == curRow) then
5988 // Loop over columns, using 1-based index
5989 set curCol = 0
5990 loop
5991 set curCol = curCol + 1
5992 exitwhen curCol > numCols
5993
5994 // Apply setting to the requested column, or all columns (if col is 0)
5995 if (col == 0 or col == curCol) then
5996 set mbitem = MultiboardGetItem(mb, curRow - 1, curCol - 1)
5997 call MultiboardSetItemWidth(mbitem, width/100.0)
5998 call MultiboardReleaseItem(mbitem)
5999 endif
6000 endloop
6001 endif
6002 endloop
6003 endfunction
6004
6005 //===========================================================================
6006 function MultiboardSetItemIconBJ takes multiboard mb, integer col, integer row, string iconFileName returns nothing
6007 local integer curRow = 0
6008 local integer curCol = 0
6009 local integer numRows = MultiboardGetRowCount(mb)
6010 local integer numCols = MultiboardGetColumnCount(mb)
6011 local multiboarditem mbitem = null
6012
6013 // Loop over rows, using 1-based index
6014 loop
6015 set curRow = curRow + 1
6016 exitwhen curRow > numRows
6017
6018 // Apply setting to the requested row, or all rows (if row is 0)
6019 if (row == 0 or row == curRow) then
6020 // Loop over columns, using 1-based index
6021 set curCol = 0
6022 loop
6023 set curCol = curCol + 1
6024 exitwhen curCol > numCols
6025
6026 // Apply setting to the requested column, or all columns (if col is 0)
6027 if (col == 0 or col == curCol) then
6028 set mbitem = MultiboardGetItem(mb, curRow - 1, curCol - 1)
6029 call MultiboardSetItemIcon(mbitem, iconFileName)
6030 call MultiboardReleaseItem(mbitem)
6031 endif
6032 endloop
6033 endif
6034 endloop
6035 endfunction
6036
6037
6038
6039 //***************************************************************************
6040 //*
6041 //* Text Tag Utility Functions
6042 //*
6043 //***************************************************************************
6044
6045 //===========================================================================
6046 // Scale the font size linearly such that size 10 equates to height 0.023.
6047 // Screen-relative font heights are harder to grasp and than font sizes.
6048 //
6049 function TextTagSize2Height takes real size returns real
6050 return size * 0.023 / 10
6051 endfunction
6052
6053 //===========================================================================
6054 // Scale the speed linearly such that speed 128 equates to 0.071.
6055 // Screen-relative speeds are hard to grasp.
6056 //
6057 function TextTagSpeed2Velocity takes real speed returns real
6058 return speed * 0.071 / 128
6059 endfunction
6060
6061 //===========================================================================
6062 function SetTextTagColorBJ takes texttag tt, real red, real green, real blue, real transparency returns nothing
6063 call SetTextTagColor(tt, PercentTo255(red), PercentTo255(green), PercentTo255(blue), PercentTo255(100.0-transparency))
6064 endfunction
6065
6066 //===========================================================================
6067 function SetTextTagVelocityBJ takes texttag tt, real speed, real angle returns nothing
6068 local real vel = TextTagSpeed2Velocity(speed)
6069 local real xvel = vel * Cos(angle * bj_DEGTORAD)
6070 local real yvel = vel * Sin(angle * bj_DEGTORAD)
6071
6072 call SetTextTagVelocity(tt, xvel, yvel)
6073 endfunction
6074
6075 //===========================================================================
6076 function SetTextTagTextBJ takes texttag tt, string s, real size returns nothing
6077 local real textHeight = TextTagSize2Height(size)
6078
6079 call SetTextTagText(tt, s, textHeight)
6080 endfunction
6081
6082 //===========================================================================
6083 function SetTextTagPosBJ takes texttag tt, location loc, real zOffset returns nothing
6084 call SetTextTagPos(tt, GetLocationX(loc), GetLocationY(loc), zOffset)
6085 endfunction
6086
6087 //===========================================================================
6088 function SetTextTagPosUnitBJ takes texttag tt, unit whichUnit, real zOffset returns nothing
6089 call SetTextTagPosUnit(tt, whichUnit, zOffset)
6090 endfunction
6091
6092 //===========================================================================
6093 function SetTextTagSuspendedBJ takes texttag tt, boolean flag returns nothing
6094 call SetTextTagSuspended(tt, flag)
6095 endfunction
6096
6097 //===========================================================================
6098 function SetTextTagPermanentBJ takes texttag tt, boolean flag returns nothing
6099 call SetTextTagPermanent(tt, flag)
6100 endfunction
6101
6102 //===========================================================================
6103 function SetTextTagAgeBJ takes texttag tt, real age returns nothing
6104 call SetTextTagAge(tt, age)
6105 endfunction
6106
6107 //===========================================================================
6108 function SetTextTagLifespanBJ takes texttag tt, real lifespan returns nothing
6109 call SetTextTagLifespan(tt, lifespan)
6110 endfunction
6111
6112 //===========================================================================
6113 function SetTextTagFadepointBJ takes texttag tt, real fadepoint returns nothing
6114 call SetTextTagFadepoint(tt, fadepoint)
6115 endfunction
6116
6117 //===========================================================================
6118 function CreateTextTagLocBJ takes string s, location loc, real zOffset, real size, real red, real green, real blue, real transparency returns texttag
6119 set bj_lastCreatedTextTag = CreateTextTag()
6120 call SetTextTagTextBJ(bj_lastCreatedTextTag, s, size)
6121 call SetTextTagPosBJ(bj_lastCreatedTextTag, loc, zOffset)
6122 call SetTextTagColorBJ(bj_lastCreatedTextTag, red, green, blue, transparency)
6123
6124 return bj_lastCreatedTextTag
6125 endfunction
6126
6127 //===========================================================================
6128 function CreateTextTagUnitBJ takes string s, unit whichUnit, real zOffset, real size, real red, real green, real blue, real transparency returns texttag
6129 set bj_lastCreatedTextTag = CreateTextTag()
6130 call SetTextTagTextBJ(bj_lastCreatedTextTag, s, size)
6131 call SetTextTagPosUnitBJ(bj_lastCreatedTextTag, whichUnit, zOffset)
6132 call SetTextTagColorBJ(bj_lastCreatedTextTag, red, green, blue, transparency)
6133
6134 return bj_lastCreatedTextTag
6135 endfunction
6136
6137 //===========================================================================
6138 function DestroyTextTagBJ takes texttag tt returns nothing
6139 call DestroyTextTag(tt)
6140 endfunction
6141
6142 //===========================================================================
6143 function ShowTextTagForceBJ takes boolean show, texttag tt, force whichForce returns nothing
6144 if (IsPlayerInForce(GetLocalPlayer(), whichForce)) then
6145 // Use only local code (no net traffic) within this block to avoid desyncs.
6146 call SetTextTagVisibility(tt, show)
6147 endif
6148 endfunction
6149
6150 //===========================================================================
6151 function GetLastCreatedTextTag takes nothing returns texttag
6152 return bj_lastCreatedTextTag
6153 endfunction
6154
6155
6156
6157 //***************************************************************************
6158 //*
6159 //* Cinematic Utility Functions
6160 //*
6161 //***************************************************************************
6162
6163 //===========================================================================
6164 function PauseGameOn takes nothing returns nothing
6165 call PauseGame(true)
6166 endfunction
6167
6168 //===========================================================================
6169 function PauseGameOff takes nothing returns nothing
6170 call PauseGame(false)
6171 endfunction
6172
6173 //===========================================================================
6174 function SetUserControlForceOn takes force whichForce returns nothing
6175 if (IsPlayerInForce(GetLocalPlayer(), whichForce)) then
6176 // Use only local code (no net traffic) within this block to avoid desyncs.
6177 call EnableUserControl(true)
6178 endif
6179 endfunction
6180
6181 //===========================================================================
6182 function SetUserControlForceOff takes force whichForce returns nothing
6183 if (IsPlayerInForce(GetLocalPlayer(), whichForce)) then
6184 // Use only local code (no net traffic) within this block to avoid desyncs.
6185 call EnableUserControl(false)
6186 endif
6187 endfunction
6188
6189 //===========================================================================
6190 function ShowInterfaceForceOn takes force whichForce, real fadeDuration returns nothing
6191 if (IsPlayerInForce(GetLocalPlayer(), whichForce)) then
6192 // Use only local code (no net traffic) within this block to avoid desyncs.
6193 call ShowInterface(true, fadeDuration)
6194 endif
6195 endfunction
6196
6197 //===========================================================================
6198 function ShowInterfaceForceOff takes force whichForce, real fadeDuration returns nothing
6199 if (IsPlayerInForce(GetLocalPlayer(), whichForce)) then
6200 // Use only local code (no net traffic) within this block to avoid desyncs.
6201 call ShowInterface(false, fadeDuration)
6202 endif
6203 endfunction
6204
6205 //===========================================================================
6206 function PingMinimapForForce takes force whichForce, real x, real y, real duration returns nothing
6207 if (IsPlayerInForce(GetLocalPlayer(), whichForce)) then
6208 // Use only local code (no net traffic) within this block to avoid desyncs.
6209 call PingMinimap(x, y, duration)
6210 //call StartSound(bj_pingMinimapSound)
6211 endif
6212 endfunction
6213
6214 //===========================================================================
6215 function PingMinimapLocForForce takes force whichForce, location loc, real duration returns nothing
6216 call PingMinimapForForce(whichForce, GetLocationX(loc), GetLocationY(loc), duration)
6217 endfunction
6218
6219 //===========================================================================
6220 function PingMinimapForPlayer takes player whichPlayer, real x, real y, real duration returns nothing
6221 if (GetLocalPlayer() == whichPlayer) then
6222 // Use only local code (no net traffic) within this block to avoid desyncs.
6223 call PingMinimap(x, y, duration)
6224 //call StartSound(bj_pingMinimapSound)
6225 endif
6226 endfunction
6227
6228 //===========================================================================
6229 function PingMinimapLocForPlayer takes player whichPlayer, location loc, real duration returns nothing
6230 call PingMinimapForPlayer(whichPlayer, GetLocationX(loc), GetLocationY(loc), duration)
6231 endfunction
6232
6233 //===========================================================================
6234 function PingMinimapForForceEx takes force whichForce, real x, real y, real duration, integer style, real red, real green, real blue returns nothing
6235 local integer red255 = PercentTo255(red)
6236 local integer green255 = PercentTo255(green)
6237 local integer blue255 = PercentTo255(blue)
6238
6239 if (IsPlayerInForce(GetLocalPlayer(), whichForce)) then
6240 // Use only local code (no net traffic) within this block to avoid desyncs.
6241
6242 // Prevent 100% red simple and flashy pings, as they become "attack" pings.
6243 if (red255 == 255) and (green255 == 0) and (blue255 == 0) then
6244 set red255 = 254
6245 endif
6246
6247 if (style == bj_MINIMAPPINGSTYLE_SIMPLE) then
6248 call PingMinimapEx(x, y, duration, red255, green255, blue255, false)
6249 elseif (style == bj_MINIMAPPINGSTYLE_FLASHY) then
6250 call PingMinimapEx(x, y, duration, red255, green255, blue255, true)
6251 elseif (style == bj_MINIMAPPINGSTYLE_ATTACK) then
6252 call PingMinimapEx(x, y, duration, 255, 0, 0, false)
6253 else
6254 // Unrecognized ping style - ignore the request.
6255 endif
6256
6257 //call StartSound(bj_pingMinimapSound)
6258 endif
6259 endfunction
6260
6261 //===========================================================================
6262 function PingMinimapLocForForceEx takes force whichForce, location loc, real duration, integer style, real red, real green, real blue returns nothing
6263 call PingMinimapForForceEx(whichForce, GetLocationX(loc), GetLocationY(loc), duration, style, red, green, blue)
6264 endfunction
6265
6266 //===========================================================================
6267 function EnableWorldFogBoundaryBJ takes boolean enable, force f returns nothing
6268 if (IsPlayerInForce(GetLocalPlayer(), f)) then
6269 // Use only local code (no net traffic) within this block to avoid desyncs.
6270 call EnableWorldFogBoundary(enable)
6271 endif
6272 endfunction
6273
6274 //===========================================================================
6275 function EnableOcclusionBJ takes boolean enable, force f returns nothing
6276 if (IsPlayerInForce(GetLocalPlayer(), f)) then
6277 // Use only local code (no net traffic) within this block to avoid desyncs.
6278 call EnableOcclusion(enable)
6279 endif
6280 endfunction
6281
6282
6283
6284 //***************************************************************************
6285 //*
6286 //* Cinematic Transmission Utility Functions
6287 //*
6288 //***************************************************************************
6289
6290 //===========================================================================
6291 // If cancelled, stop the sound and end the cinematic scene.
6292 //
6293 function CancelCineSceneBJ takes nothing returns nothing
6294 call StopSoundBJ(bj_cineSceneLastSound, true)
6295 call EndCinematicScene()
6296 endfunction
6297
6298 //===========================================================================
6299 // Init a trigger to listen for END_CINEMATIC events and respond to them if
6300 // a cinematic scene is in progress. For performance reasons, this should
6301 // only be called once a cinematic scene has been started, so that maps
6302 // lacking such scenes do not bother to register for these events.
6303 //
6304 function TryInitCinematicBehaviorBJ takes nothing returns nothing
6305 local integer index
6306
6307 if (bj_cineSceneBeingSkipped == null) then
6308 set bj_cineSceneBeingSkipped = CreateTrigger()
6309 set index = 0
6310 loop
6311 call TriggerRegisterPlayerEvent(bj_cineSceneBeingSkipped, Player(index), EVENT_PLAYER_END_CINEMATIC)
6312 set index = index + 1
6313 exitwhen index == bj_MAX_PLAYERS
6314 endloop
6315 call TriggerAddAction(bj_cineSceneBeingSkipped, function CancelCineSceneBJ)
6316 endif
6317 endfunction
6318
6319 //===========================================================================
6320 function SetCinematicSceneBJ takes sound soundHandle, integer portraitUnitId, playercolor color, string speakerTitle, string text, real sceneDuration, real voiceoverDuration returns nothing
6321 set bj_cineSceneLastSound = soundHandle
6322 call PlaySoundBJ(soundHandle)
6323 call SetCinematicScene(portraitUnitId, color, speakerTitle, text, sceneDuration, voiceoverDuration)
6324 endfunction
6325
6326 //===========================================================================
6327 function GetTransmissionDuration takes sound soundHandle, integer timeType, real timeVal returns real
6328 local real duration
6329
6330 if (timeType == bj_TIMETYPE_ADD) then
6331 set duration = GetSoundDurationBJ(soundHandle) + timeVal
6332 elseif (timeType == bj_TIMETYPE_SET) then
6333 set duration = timeVal
6334 elseif (timeType == bj_TIMETYPE_SUB) then
6335 set duration = GetSoundDurationBJ(soundHandle) - timeVal
6336 else
6337 // Unrecognized timeType - ignore timeVal.
6338 set duration = GetSoundDurationBJ(soundHandle)
6339 endif
6340
6341 // Make sure we have a non-negative duration.
6342 if (duration < 0) then
6343 set duration = 0
6344 endif
6345 return duration
6346 endfunction
6347
6348 //===========================================================================
6349 function WaitTransmissionDuration takes sound soundHandle, integer timeType, real timeVal returns nothing
6350 if (timeType == bj_TIMETYPE_SET) then
6351 // If we have a static duration wait, just perform the wait.
6352 call TriggerSleepAction(timeVal)
6353
6354 elseif (soundHandle == null) then
6355 // If the sound does not exist, perform a default length wait.
6356 call TriggerSleepAction(bj_NOTHING_SOUND_DURATION)
6357
6358 elseif (timeType == bj_TIMETYPE_SUB) then
6359 // If the transmission is cutting off the sound, wait for the sound
6360 // to be mostly finished.
6361 call WaitForSoundBJ(soundHandle, timeVal)
6362
6363 elseif (timeType == bj_TIMETYPE_ADD) then
6364 // If the transmission is extending beyond the sound's length, wait
6365 // for it to finish, and then wait the additional time.
6366 call WaitForSoundBJ(soundHandle, 0)
6367 call TriggerSleepAction(timeVal)
6368
6369 else
6370 // Unrecognized timeType - ignore.
6371 endif
6372 endfunction
6373
6374 //===========================================================================
6375 function DoTransmissionBasicsXYBJ takes integer unitId, playercolor color, real x, real y, sound soundHandle, string unitName, string message, real duration returns nothing
6376 call SetCinematicSceneBJ(soundHandle, unitId, color, unitName, message, duration + bj_TRANSMISSION_PORT_HANGTIME, duration)
6377
6378 if (unitId != 0) then
6379 call PingMinimap(x, y, bj_TRANSMISSION_PING_TIME)
6380 //call SetCameraQuickPosition(x, y)
6381 endif
6382 endfunction
6383
6384 //===========================================================================
6385 // Display a text message to a Player Group with an accompanying sound,
6386 // portrait, speech indicator, and all that good stuff.
6387 // - Query duration of sound
6388 // - Play sound
6389 // - Display text message for duration
6390 // - Display animating portrait for duration
6391 // - Display a speech indicator for the unit
6392 // - Ping the minimap
6393 //
6394 function TransmissionFromUnitWithNameBJ takes force toForce, unit whichUnit, string unitName, sound soundHandle, string message, integer timeType, real timeVal, boolean wait returns nothing
6395 call TryInitCinematicBehaviorBJ()
6396
6397 // Ensure that the time value is non-negative.
6398 set timeVal = RMaxBJ(timeVal, 0)
6399
6400 set bj_lastTransmissionDuration = GetTransmissionDuration(soundHandle, timeType, timeVal)
6401 set bj_lastPlayedSound = soundHandle
6402
6403 if (IsPlayerInForce(GetLocalPlayer(), toForce)) then
6404 // Use only local code (no net traffic) within this block to avoid desyncs.
6405
6406 if (whichUnit == null) then
6407 // If the unit reference is invalid, send the transmission from the center of the map with no portrait.
6408 call DoTransmissionBasicsXYBJ(0, PLAYER_COLOR_RED, 0, 0, soundHandle, unitName, message, bj_lastTransmissionDuration)
6409 else
6410 call DoTransmissionBasicsXYBJ(GetUnitTypeId(whichUnit), GetPlayerColor(GetOwningPlayer(whichUnit)), GetUnitX(whichUnit), GetUnitY(whichUnit), soundHandle, unitName, message, bj_lastTransmissionDuration)
6411 if (not IsUnitHidden(whichUnit)) then
6412 call UnitAddIndicator(whichUnit, bj_TRANSMISSION_IND_RED, bj_TRANSMISSION_IND_BLUE, bj_TRANSMISSION_IND_GREEN, bj_TRANSMISSION_IND_ALPHA)
6413 endif
6414 endif
6415 endif
6416
6417 if wait and (bj_lastTransmissionDuration > 0) then
6418 // call TriggerSleepAction(bj_lastTransmissionDuration)
6419 call WaitTransmissionDuration(soundHandle, timeType, timeVal)
6420 endif
6421
6422 endfunction
6423
6424 //===========================================================================
6425 // This operates like TransmissionFromUnitWithNameBJ, but for a unit type
6426 // rather than a unit instance. As such, no speech indicator is employed.
6427 //
6428 function TransmissionFromUnitTypeWithNameBJ takes force toForce, player fromPlayer, integer unitId, string unitName, location loc, sound soundHandle, string message, integer timeType, real timeVal, boolean wait returns nothing
6429 call TryInitCinematicBehaviorBJ()
6430
6431 // Ensure that the time value is non-negative.
6432 set timeVal = RMaxBJ(timeVal, 0)
6433
6434 set bj_lastTransmissionDuration = GetTransmissionDuration(soundHandle, timeType, timeVal)
6435 set bj_lastPlayedSound = soundHandle
6436
6437 if (IsPlayerInForce(GetLocalPlayer(), toForce)) then
6438 // Use only local code (no net traffic) within this block to avoid desyncs.
6439
6440 call DoTransmissionBasicsXYBJ(unitId, GetPlayerColor(fromPlayer), GetLocationX(loc), GetLocationY(loc), soundHandle, unitName, message, bj_lastTransmissionDuration)
6441 endif
6442
6443 if wait and (bj_lastTransmissionDuration > 0) then
6444 // call TriggerSleepAction(bj_lastTransmissionDuration)
6445 call WaitTransmissionDuration(soundHandle, timeType, timeVal)
6446 endif
6447
6448 endfunction
6449
6450 //===========================================================================
6451 function GetLastTransmissionDurationBJ takes nothing returns real
6452 return bj_lastTransmissionDuration
6453 endfunction
6454
6455 //===========================================================================
6456 function ForceCinematicSubtitlesBJ takes boolean flag returns nothing
6457 call ForceCinematicSubtitles(flag)
6458 endfunction
6459
6460
6461 //***************************************************************************
6462 //*
6463 //* Cinematic Mode Utility Functions
6464 //*
6465 //***************************************************************************
6466
6467 //===========================================================================
6468 // Makes many common UI settings changes at once, for use when beginning and
6469 // ending cinematic sequences. Note that some affects apply to all players,
6470 // such as game speed. This is unavoidable.
6471 // - Clear the screen of text messages
6472 // - Hide interface UI (letterbox mode)
6473 // - Hide game messages (ally under attack, etc.)
6474 // - Disable user control
6475 // - Disable occlusion
6476 // - Set game speed (for all players)
6477 // - Lock game speed (for all players)
6478 // - Disable black mask (for all players)
6479 // - Disable fog of war (for all players)
6480 // - Disable world boundary fog (for all players)
6481 // - Dim non-speech sound channels
6482 // - End any outstanding music themes
6483 // - Fix the random seed to a set value
6484 // - Reset the camera smoothing factor
6485 //
6486 function CinematicModeExBJ takes boolean cineMode, force forForce, real interfaceFadeTime returns nothing
6487 // If the game hasn't started yet, perform interface fades immediately
6488 if (not bj_gameStarted) then
6489 set interfaceFadeTime = 0
6490 endif
6491
6492 if (cineMode) then
6493 // Save the UI state so that we can restore it later.
6494 if (not bj_cineModeAlreadyIn) then
6495 set bj_cineModeAlreadyIn = true
6496 set bj_cineModePriorSpeed = GetGameSpeed()
6497 set bj_cineModePriorFogSetting = IsFogEnabled()
6498 set bj_cineModePriorMaskSetting = IsFogMaskEnabled()
6499 set bj_cineModePriorDawnDusk = IsDawnDuskEnabled()
6500 set bj_cineModeSavedSeed = GetRandomInt(0, 1000000)
6501 endif
6502
6503 // Perform local changes
6504 if (IsPlayerInForce(GetLocalPlayer(), forForce)) then
6505 // Use only local code (no net traffic) within this block to avoid desyncs.
6506 call ClearTextMessages()
6507 call ShowInterface(false, interfaceFadeTime)
6508 call EnableUserControl(false)
6509 call EnableOcclusion(false)
6510 call SetCineModeVolumeGroupsBJ()
6511 endif
6512
6513 // Perform global changes
6514 call SetGameSpeed(bj_CINEMODE_GAMESPEED)
6515 call SetMapFlag(MAP_LOCK_SPEED, true)
6516 call FogMaskEnable(false)
6517 call FogEnable(false)
6518 call EnableWorldFogBoundary(false)
6519 call EnableDawnDusk(false)
6520
6521 // Use a fixed random seed, so that cinematics play consistently.
6522 call SetRandomSeed(0)
6523 else
6524 set bj_cineModeAlreadyIn = false
6525
6526 // Perform local changes
6527 if (IsPlayerInForce(GetLocalPlayer(), forForce)) then
6528 // Use only local code (no net traffic) within this block to avoid desyncs.
6529 call ShowInterface(true, interfaceFadeTime)
6530 call EnableUserControl(true)
6531 call EnableOcclusion(true)
6532 call VolumeGroupReset()
6533 call EndThematicMusic()
6534 call CameraResetSmoothingFactorBJ()
6535 endif
6536
6537 // Perform global changes
6538 call SetMapFlag(MAP_LOCK_SPEED, false)
6539 call SetGameSpeed(bj_cineModePriorSpeed)
6540 call FogMaskEnable(bj_cineModePriorMaskSetting)
6541 call FogEnable(bj_cineModePriorFogSetting)
6542 call EnableWorldFogBoundary(true)
6543 call EnableDawnDusk(bj_cineModePriorDawnDusk)
6544 call SetRandomSeed(bj_cineModeSavedSeed)
6545 endif
6546 endfunction
6547
6548 //===========================================================================
6549 function CinematicModeBJ takes boolean cineMode, force forForce returns nothing
6550 call CinematicModeExBJ(cineMode, forForce, bj_CINEMODE_INTERFACEFADE)
6551 endfunction
6552
6553
6554
6555 //***************************************************************************
6556 //*
6557 //* Cinematic Filter Utility Functions
6558 //*
6559 //***************************************************************************
6560
6561 //===========================================================================
6562 function DisplayCineFilterBJ takes boolean flag returns nothing
6563 call DisplayCineFilter(flag)
6564 endfunction
6565
6566 //===========================================================================
6567 function CinematicFadeCommonBJ takes real red, real green, real blue, real duration, string tex, real startTrans, real endTrans returns nothing
6568 if (duration == 0) then
6569 // If the fade is instant, use the same starting and ending values,
6570 // so that we effectively do a set rather than a fade.
6571 set startTrans = endTrans
6572 endif
6573 call EnableUserUI(false)
6574 call SetCineFilterTexture(tex)
6575 call SetCineFilterBlendMode(BLEND_MODE_BLEND)
6576 call SetCineFilterTexMapFlags(TEXMAP_FLAG_NONE)
6577 call SetCineFilterStartUV(0, 0, 1, 1)
6578 call SetCineFilterEndUV(0, 0, 1, 1)
6579 call SetCineFilterStartColor(PercentTo255(red), PercentTo255(green), PercentTo255(blue), PercentTo255(100-startTrans))
6580 call SetCineFilterEndColor(PercentTo255(red), PercentTo255(green), PercentTo255(blue), PercentTo255(100-endTrans))
6581 call SetCineFilterDuration(duration)
6582 call DisplayCineFilter(true)
6583 endfunction
6584
6585 //===========================================================================
6586 function FinishCinematicFadeBJ takes nothing returns nothing
6587 call DestroyTimer(bj_cineFadeFinishTimer)
6588 set bj_cineFadeFinishTimer = null
6589 call DisplayCineFilter(false)
6590 call EnableUserUI(true)
6591 endfunction
6592
6593 //===========================================================================
6594 function FinishCinematicFadeAfterBJ takes real duration returns nothing
6595 // Create a timer to end the cinematic fade.
6596 set bj_cineFadeFinishTimer = CreateTimer()
6597 call TimerStart(bj_cineFadeFinishTimer, duration, false, function FinishCinematicFadeBJ)
6598 endfunction
6599
6600 //===========================================================================
6601 function ContinueCinematicFadeBJ takes nothing returns nothing
6602 call DestroyTimer(bj_cineFadeContinueTimer)
6603 set bj_cineFadeContinueTimer = null
6604 call CinematicFadeCommonBJ(bj_cineFadeContinueRed, bj_cineFadeContinueGreen, bj_cineFadeContinueBlue, bj_cineFadeContinueDuration, bj_cineFadeContinueTex, bj_cineFadeContinueTrans, 100)
6605 endfunction
6606
6607 //===========================================================================
6608 function ContinueCinematicFadeAfterBJ takes real duration, real red, real green, real blue, real trans, string tex returns nothing
6609 set bj_cineFadeContinueRed = red
6610 set bj_cineFadeContinueGreen = green
6611 set bj_cineFadeContinueBlue = blue
6612 set bj_cineFadeContinueTrans = trans
6613 set bj_cineFadeContinueDuration = duration
6614 set bj_cineFadeContinueTex = tex
6615
6616 // Create a timer to continue the cinematic fade.
6617 set bj_cineFadeContinueTimer = CreateTimer()
6618 call TimerStart(bj_cineFadeContinueTimer, duration, false, function ContinueCinematicFadeBJ)
6619 endfunction
6620
6621 //===========================================================================
6622 function AbortCinematicFadeBJ takes nothing returns nothing
6623 if (bj_cineFadeContinueTimer != null) then
6624 call DestroyTimer(bj_cineFadeContinueTimer)
6625 endif
6626
6627 if (bj_cineFadeFinishTimer != null) then
6628 call DestroyTimer(bj_cineFadeFinishTimer)
6629 endif
6630 endfunction
6631
6632 //===========================================================================
6633 function CinematicFadeBJ takes integer fadetype, real duration, string tex, real red, real green, real blue, real trans returns nothing
6634 if (fadetype == bj_CINEFADETYPE_FADEOUT) then
6635 // Fade out to the requested color.
6636 call AbortCinematicFadeBJ()
6637 call CinematicFadeCommonBJ(red, green, blue, duration, tex, 100, trans)
6638 elseif (fadetype == bj_CINEFADETYPE_FADEIN) then
6639 // Fade in from the requested color.
6640 call AbortCinematicFadeBJ()
6641 call CinematicFadeCommonBJ(red, green, blue, duration, tex, trans, 100)
6642 call FinishCinematicFadeAfterBJ(duration)
6643 elseif (fadetype == bj_CINEFADETYPE_FADEOUTIN) then
6644 // Fade out to the requested color, and then fade back in from it.
6645 if (duration > 0) then
6646 call AbortCinematicFadeBJ()
6647 call CinematicFadeCommonBJ(red, green, blue, duration * 0.5, tex, 100, trans)
6648 call ContinueCinematicFadeAfterBJ(duration * 0.5, red, green, blue, trans, tex)
6649 call FinishCinematicFadeAfterBJ(duration)
6650 endif
6651 else
6652 // Unrecognized fadetype - ignore the request.
6653 endif
6654 endfunction
6655
6656 //===========================================================================
6657 function CinematicFilterGenericBJ takes real duration, blendmode bmode, string tex, real red0, real green0, real blue0, real trans0, real red1, real green1, real blue1, real trans1 returns nothing
6658 call AbortCinematicFadeBJ()
6659 call SetCineFilterTexture(tex)
6660 call SetCineFilterBlendMode(bmode)
6661 call SetCineFilterTexMapFlags(TEXMAP_FLAG_NONE)
6662 call SetCineFilterStartUV(0, 0, 1, 1)
6663 call SetCineFilterEndUV(0, 0, 1, 1)
6664 call SetCineFilterStartColor(PercentTo255(red0), PercentTo255(green0), PercentTo255(blue0), PercentTo255(100-trans0))
6665 call SetCineFilterEndColor(PercentTo255(red1), PercentTo255(green1), PercentTo255(blue1), PercentTo255(100-trans1))
6666 call SetCineFilterDuration(duration)
6667 call DisplayCineFilter(true)
6668 endfunction
6669
6670
6671
6672 //***************************************************************************
6673 //*
6674 //* Rescuable Unit Utility Functions
6675 //*
6676 //***************************************************************************
6677
6678 //===========================================================================
6679 // Rescues a unit for a player. This performs the default rescue behavior,
6680 // including a rescue sound, flashing selection circle, ownership change,
6681 // and optionally a unit color change.
6682 //
6683 function RescueUnitBJ takes unit whichUnit, player rescuer, boolean changeColor returns nothing
6684 if IsUnitDeadBJ(whichUnit) or (GetOwningPlayer(whichUnit) == rescuer) then
6685 return
6686 endif
6687
6688 call StartSound(bj_rescueSound)
6689 call SetUnitOwner(whichUnit, rescuer, changeColor)
6690 call UnitAddIndicator(whichUnit, 0, 255, 0, 255)
6691 call PingMinimapForPlayer(rescuer, GetUnitX(whichUnit), GetUnitY(whichUnit), bj_RESCUE_PING_TIME)
6692 endfunction
6693
6694 //===========================================================================
6695 function TriggerActionUnitRescuedBJ takes nothing returns nothing
6696 local unit theUnit = GetTriggerUnit()
6697
6698 if IsUnitType(theUnit, UNIT_TYPE_STRUCTURE) then
6699 call RescueUnitBJ(theUnit, GetOwningPlayer(GetRescuer()), bj_rescueChangeColorBldg)
6700 else
6701 call RescueUnitBJ(theUnit, GetOwningPlayer(GetRescuer()), bj_rescueChangeColorUnit)
6702 endif
6703 endfunction
6704
6705 //===========================================================================
6706 // Attempt to init triggers for default rescue behavior. For performance
6707 // reasons, this should only be attempted if a player is set to Rescuable,
6708 // or if a specific unit is thus flagged.
6709 //
6710 function TryInitRescuableTriggersBJ takes nothing returns nothing
6711 local integer index
6712
6713 if (bj_rescueUnitBehavior == null) then
6714 set bj_rescueUnitBehavior = CreateTrigger()
6715 set index = 0
6716 loop
6717 call TriggerRegisterPlayerUnitEvent(bj_rescueUnitBehavior, Player(index), EVENT_PLAYER_UNIT_RESCUED, null)
6718 set index = index + 1
6719 exitwhen index == bj_MAX_PLAYER_SLOTS
6720 endloop
6721 call TriggerAddAction(bj_rescueUnitBehavior, function TriggerActionUnitRescuedBJ)
6722 endif
6723 endfunction
6724
6725 //===========================================================================
6726 // Determines whether or not rescued units automatically change color upon
6727 // being rescued.
6728 //
6729 function SetRescueUnitColorChangeBJ takes boolean changeColor returns nothing
6730 set bj_rescueChangeColorUnit = changeColor
6731 endfunction
6732
6733 //===========================================================================
6734 // Determines whether or not rescued buildings automatically change color
6735 // upon being rescued.
6736 //
6737 function SetRescueBuildingColorChangeBJ takes boolean changeColor returns nothing
6738 set bj_rescueChangeColorBldg = changeColor
6739 endfunction
6740
6741 //===========================================================================
6742 function MakeUnitRescuableToForceBJEnum takes nothing returns nothing
6743 call TryInitRescuableTriggersBJ()
6744 call SetUnitRescuable(bj_makeUnitRescuableUnit, GetEnumPlayer(), bj_makeUnitRescuableFlag)
6745 endfunction
6746
6747 //===========================================================================
6748 function MakeUnitRescuableToForceBJ takes unit whichUnit, boolean isRescuable, force whichForce returns nothing
6749 // Flag the unit as rescuable/unrescuable for the appropriate players.
6750 set bj_makeUnitRescuableUnit = whichUnit
6751 set bj_makeUnitRescuableFlag = isRescuable
6752 call ForForce(whichForce, function MakeUnitRescuableToForceBJEnum)
6753 endfunction
6754
6755 //===========================================================================
6756 function InitRescuableBehaviorBJ takes nothing returns nothing
6757 local integer index
6758
6759 set index = 0
6760 loop
6761 // If at least one player slot is "Rescuable"-controlled, init the
6762 // rescue behavior triggers.
6763 if (GetPlayerController(Player(index)) == MAP_CONTROL_RESCUABLE) then
6764 call TryInitRescuableTriggersBJ()
6765 return
6766 endif
6767 set index = index + 1
6768 exitwhen index == bj_MAX_PLAYERS
6769 endloop
6770 endfunction
6771
6772
6773
6774 //***************************************************************************
6775 //*
6776 //* Research and Upgrade Utility Functions
6777 //*
6778 //***************************************************************************
6779
6780 //===========================================================================
6781 function SetPlayerTechResearchedSwap takes integer techid, integer levels, player whichPlayer returns nothing
6782 call SetPlayerTechResearched(whichPlayer, techid, levels)
6783 endfunction
6784
6785 //===========================================================================
6786 function SetPlayerTechMaxAllowedSwap takes integer techid, integer maximum, player whichPlayer returns nothing
6787 call SetPlayerTechMaxAllowed(whichPlayer, techid, maximum)
6788 endfunction
6789
6790 //===========================================================================
6791 function SetPlayerMaxHeroesAllowed takes integer maximum, player whichPlayer returns nothing
6792 call SetPlayerTechMaxAllowed(whichPlayer, 'HERO', maximum)
6793 endfunction
6794
6795 //===========================================================================
6796 function GetPlayerTechCountSimple takes integer techid, player whichPlayer returns integer
6797 return GetPlayerTechCount(whichPlayer, techid, true)
6798 endfunction
6799
6800 //===========================================================================
6801 function GetPlayerTechMaxAllowedSwap takes integer techid, player whichPlayer returns integer
6802 return GetPlayerTechMaxAllowed(whichPlayer, techid)
6803 endfunction
6804
6805 //===========================================================================
6806 function SetPlayerAbilityAvailableBJ takes boolean avail, integer abilid, player whichPlayer returns nothing
6807 call SetPlayerAbilityAvailable(whichPlayer, abilid, avail)
6808 endfunction
6809
6810
6811
6812 //***************************************************************************
6813 //*
6814 //* Campaign Utility Functions
6815 //*
6816 //***************************************************************************
6817
6818 function SetCampaignMenuRaceBJ takes integer campaignNumber returns nothing
6819 if (campaignNumber == bj_CAMPAIGN_INDEX_T) then
6820 call SetCampaignMenuRace(RACE_OTHER)
6821 elseif (campaignNumber == bj_CAMPAIGN_INDEX_H) then
6822 call SetCampaignMenuRace(RACE_HUMAN)
6823 elseif (campaignNumber == bj_CAMPAIGN_INDEX_U) then
6824 call SetCampaignMenuRace(RACE_UNDEAD)
6825 elseif (campaignNumber == bj_CAMPAIGN_INDEX_O) then
6826 call SetCampaignMenuRace(RACE_ORC)
6827 elseif (campaignNumber == bj_CAMPAIGN_INDEX_N) then
6828 call SetCampaignMenuRace(RACE_NIGHTELF)
6829 elseif (campaignNumber == bj_CAMPAIGN_INDEX_XN) then
6830 call SetCampaignMenuRaceEx(bj_CAMPAIGN_OFFSET_XN)
6831 elseif (campaignNumber == bj_CAMPAIGN_INDEX_XH) then
6832 call SetCampaignMenuRaceEx(bj_CAMPAIGN_OFFSET_XH)
6833 elseif (campaignNumber == bj_CAMPAIGN_INDEX_XU) then
6834 call SetCampaignMenuRaceEx(bj_CAMPAIGN_OFFSET_XU)
6835 elseif (campaignNumber == bj_CAMPAIGN_INDEX_XO) then
6836 call SetCampaignMenuRaceEx(bj_CAMPAIGN_OFFSET_XO)
6837 else
6838 // Unrecognized campaign - ignore the request
6839 endif
6840 endfunction
6841
6842 //===========================================================================
6843 // Converts a single campaign mission designation into campaign and mission
6844 // numbers. The 1000's digit is considered the campaign index, and the 1's
6845 // digit is considered the mission index within that campaign. This is done
6846 // so that the trigger for this can use a single drop-down to list all of
6847 // the campaign missions.
6848 //
6849 function SetMissionAvailableBJ takes boolean available, integer missionIndex returns nothing
6850 local integer campaignNumber = missionIndex / 1000
6851 local integer missionNumber = missionIndex - campaignNumber * 1000
6852
6853 call SetMissionAvailable(campaignNumber, missionNumber, available)
6854 endfunction
6855
6856 //===========================================================================
6857 function SetCampaignAvailableBJ takes boolean available, integer campaignNumber returns nothing
6858 local integer campaignOffset
6859
6860 if (campaignNumber == bj_CAMPAIGN_INDEX_H) then
6861 call SetTutorialCleared(true)
6862 endif
6863
6864 if (campaignNumber == bj_CAMPAIGN_INDEX_XN) then
6865 set campaignOffset = bj_CAMPAIGN_OFFSET_XN
6866 elseif (campaignNumber == bj_CAMPAIGN_INDEX_XH) then
6867 set campaignOffset = bj_CAMPAIGN_OFFSET_XH
6868 elseif (campaignNumber == bj_CAMPAIGN_INDEX_XU) then
6869 set campaignOffset = bj_CAMPAIGN_OFFSET_XU
6870 elseif (campaignNumber == bj_CAMPAIGN_INDEX_XO) then
6871 set campaignOffset = bj_CAMPAIGN_OFFSET_XO
6872 else
6873 set campaignOffset = campaignNumber
6874 endif
6875
6876 call SetCampaignAvailable(campaignOffset, available)
6877 call SetCampaignMenuRaceBJ(campaignNumber)
6878 call ForceCampaignSelectScreen()
6879 endfunction
6880
6881 //===========================================================================
6882 function SetCinematicAvailableBJ takes boolean available, integer cinematicIndex returns nothing
6883 if ( cinematicIndex == bj_CINEMATICINDEX_TOP ) then
6884 call SetOpCinematicAvailable( bj_CAMPAIGN_INDEX_T, available )
6885 call PlayCinematic( "TutorialOp" )
6886 elseif (cinematicIndex == bj_CINEMATICINDEX_HOP) then
6887 call SetOpCinematicAvailable( bj_CAMPAIGN_INDEX_H, available )
6888 call PlayCinematic( "HumanOp" )
6889 elseif (cinematicIndex == bj_CINEMATICINDEX_HED) then
6890 call SetEdCinematicAvailable( bj_CAMPAIGN_INDEX_H, available )
6891 call PlayCinematic( "HumanEd" )
6892 elseif (cinematicIndex == bj_CINEMATICINDEX_OOP) then
6893 call SetOpCinematicAvailable( bj_CAMPAIGN_INDEX_O, available )
6894 call PlayCinematic( "OrcOp" )
6895 elseif (cinematicIndex == bj_CINEMATICINDEX_OED) then
6896 call SetEdCinematicAvailable( bj_CAMPAIGN_INDEX_O, available )
6897 call PlayCinematic( "OrcEd" )
6898 elseif (cinematicIndex == bj_CINEMATICINDEX_UOP) then
6899 call SetEdCinematicAvailable( bj_CAMPAIGN_INDEX_U, available )
6900 call PlayCinematic( "UndeadOp" )
6901 elseif (cinematicIndex == bj_CINEMATICINDEX_UED) then
6902 call SetEdCinematicAvailable( bj_CAMPAIGN_INDEX_U, available )
6903 call PlayCinematic( "UndeadEd" )
6904 elseif (cinematicIndex == bj_CINEMATICINDEX_NOP) then
6905 call SetEdCinematicAvailable( bj_CAMPAIGN_INDEX_N, available )
6906 call PlayCinematic( "NightElfOp" )
6907 elseif (cinematicIndex == bj_CINEMATICINDEX_NED) then
6908 call SetEdCinematicAvailable( bj_CAMPAIGN_INDEX_N, available )
6909 call PlayCinematic( "NightElfEd" )
6910 elseif (cinematicIndex == bj_CINEMATICINDEX_XOP) then
6911 call SetOpCinematicAvailable( bj_CAMPAIGN_OFFSET_XN, available )
6912 call PlayCinematic( "IntroX" )
6913 elseif (cinematicIndex == bj_CINEMATICINDEX_XED) then
6914 call SetEdCinematicAvailable( bj_CAMPAIGN_OFFSET_XU, available )
6915 call PlayCinematic( "OutroX" )
6916 else
6917 // Unrecognized cinematic - ignore the request.
6918 endif
6919 endfunction
6920
6921 //===========================================================================
6922 function InitGameCacheBJ takes string campaignFile returns gamecache
6923 set bj_lastCreatedGameCache = InitGameCache(campaignFile)
6924 return bj_lastCreatedGameCache
6925 endfunction
6926
6927 //===========================================================================
6928 function SaveGameCacheBJ takes gamecache cache returns boolean
6929 return SaveGameCache(cache)
6930 endfunction
6931
6932 //===========================================================================
6933 function GetLastCreatedGameCacheBJ takes nothing returns gamecache
6934 return bj_lastCreatedGameCache
6935 endfunction
6936
6937 //===========================================================================
6938 function StoreRealBJ takes real value, string key, string missionKey, gamecache cache returns nothing
6939 call StoreReal(cache, missionKey, key, value)
6940 endfunction
6941
6942 //===========================================================================
6943 function StoreIntegerBJ takes integer value, string key, string missionKey, gamecache cache returns nothing
6944 call StoreInteger(cache, missionKey, key, value)
6945 endfunction
6946
6947 //===========================================================================
6948 function StoreBooleanBJ takes boolean value, string key, string missionKey, gamecache cache returns nothing
6949 call StoreBoolean(cache, missionKey, key, value)
6950 endfunction
6951
6952 //===========================================================================
6953 function StoreStringBJ takes string value, string key, string missionKey, gamecache cache returns boolean
6954 return StoreString(cache, missionKey, key, value)
6955 endfunction
6956
6957 //===========================================================================
6958 function StoreUnitBJ takes unit whichUnit, string key, string missionKey, gamecache cache returns boolean
6959 return StoreUnit(cache, missionKey, key, whichUnit)
6960 endfunction
6961
6962 //===========================================================================
6963 function GetStoredRealBJ takes string key, string missionKey, gamecache cache returns real
6964 //call SyncStoredReal(cache, missionKey, key)
6965 return GetStoredReal(cache, missionKey, key)
6966 endfunction
6967
6968 //===========================================================================
6969 function GetStoredIntegerBJ takes string key, string missionKey, gamecache cache returns integer
6970 //call SyncStoredInteger(cache, missionKey, key)
6971 return GetStoredInteger(cache, missionKey, key)
6972 endfunction
6973
6974 //===========================================================================
6975 function GetStoredBooleanBJ takes string key, string missionKey, gamecache cache returns boolean
6976 //call SyncStoredBoolean(cache, missionKey, key)
6977 return GetStoredBoolean(cache, missionKey, key)
6978 endfunction
6979
6980 //===========================================================================
6981 function GetStoredStringBJ takes string key, string missionKey, gamecache cache returns string
6982 local string s
6983
6984 //call SyncStoredString(cache, missionKey, key)
6985 set s = GetStoredString(cache, missionKey, key)
6986 if (s == null) then
6987 return ""
6988 else
6989 return s
6990 endif
6991 endfunction
6992
6993 //===========================================================================
6994 function RestoreUnitLocFacingAngleBJ takes string key, string missionKey, gamecache cache, player forWhichPlayer, location loc, real facing returns unit
6995 //call SyncStoredUnit(cache, missionKey, key)
6996 set bj_lastLoadedUnit = RestoreUnit(cache, missionKey, key, forWhichPlayer, GetLocationX(loc), GetLocationY(loc), facing)
6997 return bj_lastLoadedUnit
6998 endfunction
6999
7000 //===========================================================================
7001 function RestoreUnitLocFacingPointBJ takes string key, string missionKey, gamecache cache, player forWhichPlayer, location loc, location lookAt returns unit
7002 //call SyncStoredUnit(cache, missionKey, key)
7003 return RestoreUnitLocFacingAngleBJ(key, missionKey, cache, forWhichPlayer, loc, AngleBetweenPoints(loc, lookAt))
7004 endfunction
7005
7006 //===========================================================================
7007 function GetLastRestoredUnitBJ takes nothing returns unit
7008 return bj_lastLoadedUnit
7009 endfunction
7010
7011 //===========================================================================
7012 function FlushGameCacheBJ takes gamecache cache returns nothing
7013 call FlushGameCache(cache)
7014 endfunction
7015
7016 //===========================================================================
7017 function FlushStoredMissionBJ takes string missionKey, gamecache cache returns nothing
7018 call FlushStoredMission(cache, missionKey)
7019 endfunction
7020
7021 //===========================================================================
7022 function HaveStoredValue takes string key, integer valueType, string missionKey, gamecache cache returns boolean
7023 if (valueType == bj_GAMECACHE_BOOLEAN) then
7024 return HaveStoredBoolean(cache, missionKey, key)
7025 elseif (valueType == bj_GAMECACHE_INTEGER) then
7026 return HaveStoredInteger(cache, missionKey, key)
7027 elseif (valueType == bj_GAMECACHE_REAL) then
7028 return HaveStoredReal(cache, missionKey, key)
7029 elseif (valueType == bj_GAMECACHE_UNIT) then
7030 return HaveStoredUnit(cache, missionKey, key)
7031 elseif (valueType == bj_GAMECACHE_STRING) then
7032 return HaveStoredString(cache, missionKey, key)
7033 else
7034 // Unrecognized value type - ignore the request.
7035 return false
7036 endif
7037 endfunction
7038
7039 //===========================================================================
7040 function ShowCustomCampaignButton takes boolean show, integer whichButton returns nothing
7041 call SetCustomCampaignButtonVisible(whichButton - 1, show)
7042 endfunction
7043
7044 //===========================================================================
7045 function IsCustomCampaignButtonVisibile takes integer whichButton returns boolean
7046 return GetCustomCampaignButtonVisible(whichButton - 1)
7047 endfunction
7048
7049 //===========================================================================
7050 function LoadGameBJ takes string loadFileName, boolean doScoreScreen returns nothing
7051 call LoadGame(loadFileName, doScoreScreen)
7052 endfunction
7053
7054 //===========================================================================
7055 function SaveAndChangeLevelBJ takes string saveFileName, string newLevel, boolean doScoreScreen returns nothing
7056 call SaveGame(saveFileName)
7057 call ChangeLevel(newLevel, doScoreScreen)
7058 endfunction
7059
7060 //===========================================================================
7061 function SaveAndLoadGameBJ takes string saveFileName, string loadFileName, boolean doScoreScreen returns nothing
7062 call SaveGame(saveFileName)
7063 call LoadGame(loadFileName, doScoreScreen)
7064 endfunction
7065
7066 //===========================================================================
7067 function RenameSaveDirectoryBJ takes string sourceDirName, string destDirName returns boolean
7068 return RenameSaveDirectory(sourceDirName, destDirName)
7069 endfunction
7070
7071 //===========================================================================
7072 function RemoveSaveDirectoryBJ takes string sourceDirName returns boolean
7073 return RemoveSaveDirectory(sourceDirName)
7074 endfunction
7075
7076 //===========================================================================
7077 function CopySaveGameBJ takes string sourceSaveName, string destSaveName returns boolean
7078 return CopySaveGame(sourceSaveName, destSaveName)
7079 endfunction
7080
7081
7082
7083 //***************************************************************************
7084 //*
7085 //* Miscellaneous Utility Functions
7086 //*
7087 //***************************************************************************
7088
7089 //===========================================================================
7090 function GetPlayerStartLocationX takes player whichPlayer returns real
7091 return GetStartLocationX(GetPlayerStartLocation(whichPlayer))
7092 endfunction
7093
7094 //===========================================================================
7095 function GetPlayerStartLocationY takes player whichPlayer returns real
7096 return GetStartLocationY(GetPlayerStartLocation(whichPlayer))
7097 endfunction
7098
7099 //===========================================================================
7100 function GetPlayerStartLocationLoc takes player whichPlayer returns location
7101 return GetStartLocationLoc(GetPlayerStartLocation(whichPlayer))
7102 endfunction
7103
7104 //===========================================================================
7105 function GetRectCenter takes rect whichRect returns location
7106 return Location(GetRectCenterX(whichRect), GetRectCenterY(whichRect))
7107 endfunction
7108
7109 //===========================================================================
7110 function IsPlayerSlotState takes player whichPlayer, playerslotstate whichState returns boolean
7111 return GetPlayerSlotState(whichPlayer) == whichState
7112 endfunction
7113
7114 //===========================================================================
7115 function GetFadeFromSeconds takes real seconds returns integer
7116 if (seconds != 0) then
7117 return 128 / seconds
7118 else
7119 return 10000
7120 endif
7121 endfunction
7122
7123 //===========================================================================
7124 function AdjustPlayerStateSimpleBJ takes player whichPlayer, playerstate whichPlayerState, integer delta returns nothing
7125 call SetPlayerState(whichPlayer, whichPlayerState, GetPlayerState(whichPlayer, whichPlayerState) + delta)
7126 endfunction
7127
7128 //===========================================================================
7129 function AdjustPlayerStateBJ takes integer delta, player whichPlayer, playerstate whichPlayerState returns nothing
7130 // If the change was positive, apply the difference to the player's
7131 // gathered resources property as well.
7132 if (delta > 0) then
7133 if (whichPlayerState == PLAYER_STATE_RESOURCE_GOLD) then
7134 call AdjustPlayerStateSimpleBJ(whichPlayer, PLAYER_STATE_GOLD_GATHERED, delta)
7135 elseif (whichPlayerState == PLAYER_STATE_RESOURCE_LUMBER) then
7136 call AdjustPlayerStateSimpleBJ(whichPlayer, PLAYER_STATE_LUMBER_GATHERED, delta)
7137 endif
7138 endif
7139
7140 call AdjustPlayerStateSimpleBJ(whichPlayer, whichPlayerState, delta)
7141 endfunction
7142
7143 //===========================================================================
7144 function SetPlayerStateBJ takes player whichPlayer, playerstate whichPlayerState, integer value returns nothing
7145 local integer oldValue = GetPlayerState(whichPlayer, whichPlayerState)
7146 call AdjustPlayerStateBJ(value - oldValue, whichPlayer, whichPlayerState)
7147 endfunction
7148
7149 //===========================================================================
7150 function SetPlayerFlagBJ takes playerstate whichPlayerFlag, boolean flag, player whichPlayer returns nothing
7151 call SetPlayerState(whichPlayer, whichPlayerFlag, IntegerTertiaryOp(flag, 1, 0))
7152 endfunction
7153
7154 //===========================================================================
7155 function SetPlayerTaxRateBJ takes integer rate, playerstate whichResource, player sourcePlayer, player otherPlayer returns nothing
7156 call SetPlayerTaxRate(sourcePlayer, otherPlayer, whichResource, rate)
7157 endfunction
7158
7159 //===========================================================================
7160 function GetPlayerTaxRateBJ takes playerstate whichResource, player sourcePlayer, player otherPlayer returns integer
7161 return GetPlayerTaxRate(sourcePlayer, otherPlayer, whichResource)
7162 endfunction
7163
7164 //===========================================================================
7165 function IsPlayerFlagSetBJ takes playerstate whichPlayerFlag, player whichPlayer returns boolean
7166 return GetPlayerState(whichPlayer, whichPlayerFlag) == 1
7167 endfunction
7168
7169 //===========================================================================
7170 function AddResourceAmountBJ takes integer delta, unit whichUnit returns nothing
7171 call AddResourceAmount(whichUnit, delta)
7172 endfunction
7173
7174 //===========================================================================
7175 function GetConvertedPlayerId takes player whichPlayer returns integer
7176 return GetPlayerId(whichPlayer) + 1
7177 endfunction
7178
7179 //===========================================================================
7180 function ConvertedPlayer takes integer convertedPlayerId returns player
7181 return Player(convertedPlayerId - 1)
7182 endfunction
7183
7184 //===========================================================================
7185 function GetRectWidthBJ takes rect r returns real
7186 return GetRectMaxX(r) - GetRectMinX(r)
7187 endfunction
7188
7189 //===========================================================================
7190 function GetRectHeightBJ takes rect r returns real
7191 return GetRectMaxY(r) - GetRectMinY(r)
7192 endfunction
7193
7194 //===========================================================================
7195 // Replaces a gold mine with a blighted gold mine for the given player.
7196 //
7197 function BlightGoldMineForPlayerBJ takes unit goldMine, player whichPlayer returns unit
7198 local real mineX
7199 local real mineY
7200 local integer mineGold
7201 local unit newMine
7202
7203 // Make sure we're replacing a Gold Mine and not some other type of unit.
7204 if GetUnitTypeId(goldMine) != 'ngol' then
7205 return null
7206 endif
7207
7208 // Save the Gold Mine's properties and remove it.
7209 set mineX = GetUnitX(goldMine)
7210 set mineY = GetUnitY(goldMine)
7211 set mineGold = GetResourceAmount(goldMine)
7212 call RemoveUnit(goldMine)
7213
7214 // Create a Haunted Gold Mine to replace the Gold Mine.
7215 set newMine = CreateBlightedGoldmine(whichPlayer, mineX, mineY, bj_UNIT_FACING)
7216 call SetResourceAmount(newMine, mineGold)
7217 return newMine
7218 endfunction
7219
7220 //===========================================================================
7221 function BlightGoldMineForPlayer takes unit goldMine, player whichPlayer returns unit
7222 set bj_lastHauntedGoldMine = BlightGoldMineForPlayerBJ(goldMine, whichPlayer)
7223 return bj_lastHauntedGoldMine
7224 endfunction
7225
7226 //===========================================================================
7227 function GetLastHauntedGoldMine takes nothing returns unit
7228 return bj_lastHauntedGoldMine
7229 endfunction
7230
7231 //===========================================================================
7232 function IsPointBlightedBJ takes location where returns boolean
7233 return IsPointBlighted(GetLocationX(where), GetLocationY(where))
7234 endfunction
7235
7236 //===========================================================================
7237 function SetPlayerColorBJEnum takes nothing returns nothing
7238 call SetUnitColor(GetEnumUnit(), bj_setPlayerTargetColor)
7239 endfunction
7240
7241 //===========================================================================
7242 function SetPlayerColorBJ takes player whichPlayer, playercolor color, boolean changeExisting returns nothing
7243 local group g
7244
7245 call SetPlayerColor(whichPlayer, color)
7246 if changeExisting then
7247 set bj_setPlayerTargetColor = color
7248 set g = CreateGroup()
7249 call GroupEnumUnitsOfPlayer(g, whichPlayer, null)
7250 call ForGroup(g, function SetPlayerColorBJEnum)
7251 call DestroyGroup(g)
7252 endif
7253 endfunction
7254
7255 //===========================================================================
7256 function SetPlayerUnitAvailableBJ takes integer unitId, boolean allowed, player whichPlayer returns nothing
7257 if allowed then
7258 call SetPlayerTechMaxAllowed(whichPlayer, unitId, -1)
7259 else
7260 call SetPlayerTechMaxAllowed(whichPlayer, unitId, 0)
7261 endif
7262 endfunction
7263
7264 //===========================================================================
7265 function LockGameSpeedBJ takes nothing returns nothing
7266 call SetMapFlag(MAP_LOCK_SPEED, true)
7267 endfunction
7268
7269 //===========================================================================
7270 function UnlockGameSpeedBJ takes nothing returns nothing
7271 call SetMapFlag(MAP_LOCK_SPEED, false)
7272 endfunction
7273
7274 //===========================================================================
7275 function IssueTargetOrderBJ takes unit whichUnit, string order, widget targetWidget returns boolean
7276 return IssueTargetOrder( whichUnit, order, targetWidget )
7277 endfunction
7278
7279 //===========================================================================
7280 function IssuePointOrderLocBJ takes unit whichUnit, string order, location whichLocation returns boolean
7281 return IssuePointOrderLoc( whichUnit, order, whichLocation )
7282 endfunction
7283
7284 //===========================================================================
7285 // Two distinct trigger actions can't share the same function name, so this
7286 // dummy function simply mimics the behavior of an existing call.
7287 //
7288 function IssueTargetDestructableOrder takes unit whichUnit, string order, widget targetWidget returns boolean
7289 return IssueTargetOrder( whichUnit, order, targetWidget )
7290 endfunction
7291
7292 function IssueTargetItemOrder takes unit whichUnit, string order, widget targetWidget returns boolean
7293 return IssueTargetOrder( whichUnit, order, targetWidget )
7294 endfunction
7295
7296 //===========================================================================
7297 function IssueImmediateOrderBJ takes unit whichUnit, string order returns boolean
7298 return IssueImmediateOrder( whichUnit, order )
7299 endfunction
7300
7301 //===========================================================================
7302 function GroupTargetOrderBJ takes group whichGroup, string order, widget targetWidget returns boolean
7303 return GroupTargetOrder( whichGroup, order, targetWidget )
7304 endfunction
7305
7306 //===========================================================================
7307 function GroupPointOrderLocBJ takes group whichGroup, string order, location whichLocation returns boolean
7308 return GroupPointOrderLoc( whichGroup, order, whichLocation )
7309 endfunction
7310
7311 //===========================================================================
7312 function GroupImmediateOrderBJ takes group whichGroup, string order returns boolean
7313 return GroupImmediateOrder( whichGroup, order )
7314 endfunction
7315
7316 //===========================================================================
7317 // Two distinct trigger actions can't share the same function name, so this
7318 // dummy function simply mimics the behavior of an existing call.
7319 //
7320 function GroupTargetDestructableOrder takes group whichGroup, string order, widget targetWidget returns boolean
7321 return GroupTargetOrder( whichGroup, order, targetWidget )
7322 endfunction
7323
7324 function GroupTargetItemOrder takes group whichGroup, string order, widget targetWidget returns boolean
7325 return GroupTargetOrder( whichGroup, order, targetWidget )
7326 endfunction
7327
7328 //===========================================================================
7329 function GetDyingDestructable takes nothing returns destructable
7330 return GetTriggerWidget()
7331 endfunction
7332
7333 //===========================================================================
7334 // Rally point setting
7335 //
7336 function SetUnitRallyPoint takes unit whichUnit, location targPos returns nothing
7337 call IssuePointOrderLocBJ(whichUnit, "setrally", targPos)
7338 endfunction
7339
7340 //===========================================================================
7341 function SetUnitRallyUnit takes unit whichUnit, unit targUnit returns nothing
7342 call IssueTargetOrder(whichUnit, "setrally", targUnit)
7343 endfunction
7344
7345 //===========================================================================
7346 function SetUnitRallyDestructable takes unit whichUnit, destructable targDest returns nothing
7347 call IssueTargetOrder(whichUnit, "setrally", targDest)
7348 endfunction
7349
7350 //===========================================================================
7351 // Utility function for use by editor-generated item drop table triggers.
7352 // This function is added as an action to all destructable drop triggers,
7353 // so that a widget drop may be differentiated from a unit drop.
7354 //
7355 function SaveDyingWidget takes nothing returns nothing
7356 set bj_lastDyingWidget = GetTriggerWidget()
7357 endfunction
7358
7359 //===========================================================================
7360 function SetBlightRectBJ takes boolean addBlight, player whichPlayer, rect r returns nothing
7361 call SetBlightRect(whichPlayer, r, addBlight)
7362 endfunction
7363
7364 //===========================================================================
7365 function SetBlightRadiusLocBJ takes boolean addBlight, player whichPlayer, location loc, real radius returns nothing
7366 call SetBlightLoc(whichPlayer, loc, radius, addBlight)
7367 endfunction
7368
7369 //===========================================================================
7370 function GetAbilityName takes integer abilcode returns string
7371 return GetObjectName(abilcode)
7372 endfunction
7373
7374
7375 //***************************************************************************
7376 //*
7377 //* Melee Template Visibility Settings
7378 //*
7379 //***************************************************************************
7380
7381 //===========================================================================
7382 function MeleeStartingVisibility takes nothing returns nothing
7383 // Start by setting the ToD.
7384 call SetFloatGameState(GAME_STATE_TIME_OF_DAY, bj_MELEE_STARTING_TOD)
7385
7386 // call FogMaskEnable(true)
7387 // call FogEnable(true)
7388 endfunction
7389
7390
7391
7392 //***************************************************************************
7393 //*
7394 //* Melee Template Starting Resources
7395 //*
7396 //***************************************************************************
7397
7398 //===========================================================================
7399 function MeleeStartingResources takes nothing returns nothing
7400 local integer index
7401 local player indexPlayer
7402 local version v
7403 local integer startingGold
7404 local integer startingLumber
7405
7406 set v = VersionGet()
7407 if (v == VERSION_REIGN_OF_CHAOS) then
7408 set startingGold = bj_MELEE_STARTING_GOLD_V0
7409 set startingLumber = bj_MELEE_STARTING_LUMBER_V0
7410 else
7411 set startingGold = bj_MELEE_STARTING_GOLD_V1
7412 set startingLumber = bj_MELEE_STARTING_LUMBER_V1
7413 endif
7414
7415 // Set each player's starting resources.
7416 set index = 0
7417 loop
7418 set indexPlayer = Player(index)
7419 if (GetPlayerSlotState(indexPlayer) == PLAYER_SLOT_STATE_PLAYING) then
7420 call SetPlayerState(indexPlayer, PLAYER_STATE_RESOURCE_GOLD, startingGold)
7421 call SetPlayerState(indexPlayer, PLAYER_STATE_RESOURCE_LUMBER, startingLumber)
7422 endif
7423
7424 set index = index + 1
7425 exitwhen index == bj_MAX_PLAYERS
7426 endloop
7427 endfunction
7428
7429
7430
7431 //***************************************************************************
7432 //*
7433 //* Melee Template Hero Limit
7434 //*
7435 //***************************************************************************
7436
7437 //===========================================================================
7438 function ReducePlayerTechMaxAllowed takes player whichPlayer, integer techId, integer limit returns nothing
7439 local integer oldMax = GetPlayerTechMaxAllowed(whichPlayer, techId)
7440
7441 // A value of -1 is used to indicate no limit, so check for that as well.
7442 if (oldMax < 0 or oldMax > limit) then
7443 call SetPlayerTechMaxAllowed(whichPlayer, techId, limit)
7444 endif
7445 endfunction
7446
7447 //===========================================================================
7448 function MeleeStartingHeroLimit takes nothing returns nothing
7449 local integer index
7450
7451 set index = 0
7452 loop
7453 // max heroes per player
7454 call SetPlayerMaxHeroesAllowed(bj_MELEE_HERO_LIMIT, Player(index))
7455
7456 // each player is restricted to a limit per hero type as well
7457 call ReducePlayerTechMaxAllowed(Player(index), 'Hamg', bj_MELEE_HERO_TYPE_LIMIT)
7458 call ReducePlayerTechMaxAllowed(Player(index), 'Hmkg', bj_MELEE_HERO_TYPE_LIMIT)
7459 call ReducePlayerTechMaxAllowed(Player(index), 'Hpal', bj_MELEE_HERO_TYPE_LIMIT)
7460 call ReducePlayerTechMaxAllowed(Player(index), 'Hblm', bj_MELEE_HERO_TYPE_LIMIT)
7461
7462 call ReducePlayerTechMaxAllowed(Player(index), 'Obla', bj_MELEE_HERO_TYPE_LIMIT)
7463 call ReducePlayerTechMaxAllowed(Player(index), 'Ofar', bj_MELEE_HERO_TYPE_LIMIT)
7464 call ReducePlayerTechMaxAllowed(Player(index), 'Otch', bj_MELEE_HERO_TYPE_LIMIT)
7465 call ReducePlayerTechMaxAllowed(Player(index), 'Oshd', bj_MELEE_HERO_TYPE_LIMIT)
7466
7467 call ReducePlayerTechMaxAllowed(Player(index), 'Edem', bj_MELEE_HERO_TYPE_LIMIT)
7468 call ReducePlayerTechMaxAllowed(Player(index), 'Ekee', bj_MELEE_HERO_TYPE_LIMIT)
7469 call ReducePlayerTechMaxAllowed(Player(index), 'Emoo', bj_MELEE_HERO_TYPE_LIMIT)
7470 call ReducePlayerTechMaxAllowed(Player(index), 'Ewar', bj_MELEE_HERO_TYPE_LIMIT)
7471
7472 call ReducePlayerTechMaxAllowed(Player(index), 'Udea', bj_MELEE_HERO_TYPE_LIMIT)
7473 call ReducePlayerTechMaxAllowed(Player(index), 'Udre', bj_MELEE_HERO_TYPE_LIMIT)
7474 call ReducePlayerTechMaxAllowed(Player(index), 'Ulic', bj_MELEE_HERO_TYPE_LIMIT)
7475 call ReducePlayerTechMaxAllowed(Player(index), 'Ucrl', bj_MELEE_HERO_TYPE_LIMIT)
7476
7477 call ReducePlayerTechMaxAllowed(Player(index), 'Npbm', bj_MELEE_HERO_TYPE_LIMIT)
7478 call ReducePlayerTechMaxAllowed(Player(index), 'Nbrn', bj_MELEE_HERO_TYPE_LIMIT)
7479 call ReducePlayerTechMaxAllowed(Player(index), 'Nngs', bj_MELEE_HERO_TYPE_LIMIT)
7480 call ReducePlayerTechMaxAllowed(Player(index), 'Nplh', bj_MELEE_HERO_TYPE_LIMIT)
7481 call ReducePlayerTechMaxAllowed(Player(index), 'Nbst', bj_MELEE_HERO_TYPE_LIMIT)
7482 call ReducePlayerTechMaxAllowed(Player(index), 'Nalc', bj_MELEE_HERO_TYPE_LIMIT)
7483 call ReducePlayerTechMaxAllowed(Player(index), 'Ntin', bj_MELEE_HERO_TYPE_LIMIT)
7484 call ReducePlayerTechMaxAllowed(Player(index), 'Nfir', bj_MELEE_HERO_TYPE_LIMIT)
7485
7486 set index = index + 1
7487 exitwhen index == bj_MAX_PLAYERS
7488 endloop
7489 endfunction
7490
7491
7492
7493 //***************************************************************************
7494 //*
7495 //* Melee Template Granted Hero Items
7496 //*
7497 //***************************************************************************
7498
7499 //===========================================================================
7500 function MeleeTrainedUnitIsHeroBJFilter takes nothing returns boolean
7501 return IsUnitType(GetFilterUnit(), UNIT_TYPE_HERO)
7502 endfunction
7503
7504 //===========================================================================
7505 // The first N heroes trained or hired for each player start off with a
7506 // standard set of items. This is currently:
7507 // - 1x Scroll of Town Portal
7508 //
7509 function MeleeGrantItemsToHero takes unit whichUnit returns nothing
7510 local integer owner = GetPlayerId(GetOwningPlayer(whichUnit))
7511
7512 // If we haven't twinked N heroes for this player yet, twink away.
7513 if (bj_meleeTwinkedHeroes[owner] < bj_MELEE_MAX_TWINKED_HEROES) then
7514 call UnitAddItemById(whichUnit, 'stwp')
7515 set bj_meleeTwinkedHeroes[owner] = bj_meleeTwinkedHeroes[owner] + 1
7516 endif
7517 endfunction
7518
7519 //===========================================================================
7520 function MeleeGrantItemsToTrainedHero takes nothing returns nothing
7521 call MeleeGrantItemsToHero(GetTrainedUnit())
7522 endfunction
7523
7524 //===========================================================================
7525 function MeleeGrantItemsToHiredHero takes nothing returns nothing
7526 call MeleeGrantItemsToHero(GetSoldUnit())
7527 endfunction
7528
7529 //===========================================================================
7530 function MeleeGrantHeroItems takes nothing returns nothing
7531 local integer index
7532 local trigger trig
7533
7534 // Initialize the twinked hero counts.
7535 set index = 0
7536 loop
7537 set bj_meleeTwinkedHeroes[index] = 0
7538
7539 set index = index + 1
7540 exitwhen index == bj_MAX_PLAYER_SLOTS
7541 endloop
7542
7543 // Register for an event whenever a hero is trained, so that we can give
7544 // him/her their starting items.
7545 set index = 0
7546 loop
7547 set trig = CreateTrigger()
7548 call TriggerRegisterPlayerUnitEvent(trig, Player(index), EVENT_PLAYER_UNIT_TRAIN_FINISH, filterMeleeTrainedUnitIsHeroBJ)
7549 call TriggerAddAction(trig, function MeleeGrantItemsToTrainedHero)
7550
7551 set index = index + 1
7552 exitwhen index == bj_MAX_PLAYERS
7553 endloop
7554
7555 // Register for an event whenever a neutral hero is hired, so that we
7556 // can give him/her their starting items.
7557 set trig = CreateTrigger()
7558 call TriggerRegisterPlayerUnitEvent(trig, Player(PLAYER_NEUTRAL_PASSIVE), EVENT_PLAYER_UNIT_SELL, filterMeleeTrainedUnitIsHeroBJ)
7559 call TriggerAddAction(trig, function MeleeGrantItemsToHiredHero)
7560
7561 // Flag that we are giving starting items to heroes, so that the melee
7562 // starting units code can create them as necessary.
7563 set bj_meleeGrantHeroItems = true
7564 endfunction
7565
7566
7567
7568 //***************************************************************************
7569 //*
7570 //* Melee Template Clear Start Locations
7571 //*
7572 //***************************************************************************
7573
7574 //===========================================================================
7575 function MeleeClearExcessUnit takes nothing returns nothing
7576 local unit theUnit = GetEnumUnit()
7577 local integer owner = GetPlayerId(GetOwningPlayer(theUnit))
7578
7579 if (owner == PLAYER_NEUTRAL_AGGRESSIVE) then
7580 // Remove any Neutral Hostile units from the area.
7581 call RemoveUnit(GetEnumUnit())
7582 elseif (owner == PLAYER_NEUTRAL_PASSIVE) then
7583 // Remove non-structure Neutral Passive units from the area.
7584 if not IsUnitType(theUnit, UNIT_TYPE_STRUCTURE) then
7585 call RemoveUnit(GetEnumUnit())
7586 endif
7587 endif
7588 endfunction
7589
7590 //===========================================================================
7591 function MeleeClearNearbyUnits takes real x, real y, real range returns nothing
7592 local group nearbyUnits
7593
7594 set nearbyUnits = CreateGroup()
7595 call GroupEnumUnitsInRange(nearbyUnits, x, y, range, null)
7596 call ForGroup(nearbyUnits, function MeleeClearExcessUnit)
7597 call DestroyGroup(nearbyUnits)
7598 endfunction
7599
7600 //===========================================================================
7601 function MeleeClearExcessUnits takes nothing returns nothing
7602 local integer index
7603 local real locX
7604 local real locY
7605 local player indexPlayer
7606
7607 set index = 0
7608 loop
7609 set indexPlayer = Player(index)
7610
7611 // If the player slot is being used, clear any nearby creeps.
7612 if (GetPlayerSlotState(indexPlayer) == PLAYER_SLOT_STATE_PLAYING) then
7613 set locX = GetStartLocationX(GetPlayerStartLocation(indexPlayer))
7614 set locY = GetStartLocationY(GetPlayerStartLocation(indexPlayer))
7615
7616 call MeleeClearNearbyUnits(locX, locY, bj_MELEE_CLEAR_UNITS_RADIUS)
7617 endif
7618
7619 set index = index + 1
7620 exitwhen index == bj_MAX_PLAYERS
7621 endloop
7622 endfunction
7623
7624
7625
7626 //***************************************************************************
7627 //*
7628 //* Melee Template Starting Units
7629 //*
7630 //***************************************************************************
7631
7632 //===========================================================================
7633 function MeleeEnumFindNearestMine takes nothing returns nothing
7634 local unit enumUnit = GetEnumUnit()
7635 local real dist
7636 local location unitLoc
7637
7638 if (GetUnitTypeId(enumUnit) == 'ngol') then
7639 set unitLoc = GetUnitLoc(enumUnit)
7640 set dist = DistanceBetweenPoints(unitLoc, bj_meleeNearestMineToLoc)
7641 call RemoveLocation(unitLoc)
7642
7643 // If this is our first mine, or the closest thusfar, use it instead.
7644 if (bj_meleeNearestMineDist < 0) or (dist < bj_meleeNearestMineDist) then
7645 set bj_meleeNearestMine = enumUnit
7646 set bj_meleeNearestMineDist = dist
7647 endif
7648 endif
7649 endfunction
7650
7651 //===========================================================================
7652 function MeleeFindNearestMine takes location src, real range returns unit
7653 local group nearbyMines
7654
7655 set bj_meleeNearestMine = null
7656 set bj_meleeNearestMineDist = -1
7657 set bj_meleeNearestMineToLoc = src
7658
7659 set nearbyMines = CreateGroup()
7660 call GroupEnumUnitsInRangeOfLoc(nearbyMines, src, range, null)
7661 call ForGroup(nearbyMines, function MeleeEnumFindNearestMine)
7662 call DestroyGroup(nearbyMines)
7663
7664 return bj_meleeNearestMine
7665 endfunction
7666
7667 //===========================================================================
7668 function MeleeRandomHeroLoc takes player p, integer id1, integer id2, integer id3, integer id4, location loc returns unit
7669 local unit hero = null
7670 local integer roll
7671 local integer pick
7672 local version v
7673
7674 // The selection of heroes is dependant on the game version.
7675 set v = VersionGet()
7676 if (v == VERSION_REIGN_OF_CHAOS) then
7677 set roll = GetRandomInt(1,3)
7678 else
7679 set roll = GetRandomInt(1,4)
7680 endif
7681
7682 // Translate the roll into a unitid.
7683 if roll == 1 then
7684 set pick = id1
7685 elseif roll == 2 then
7686 set pick = id2
7687 elseif roll == 3 then
7688 set pick = id3
7689 elseif roll == 4 then
7690 set pick = id4
7691 else
7692 // Unrecognized id index - pick the first hero in the list.
7693 set pick = id1
7694 endif
7695
7696 // Create the hero.
7697 set hero = CreateUnitAtLoc(p, pick, loc, bj_UNIT_FACING)
7698 if bj_meleeGrantHeroItems then
7699 call MeleeGrantItemsToHero(hero)
7700 endif
7701 return hero
7702 endfunction
7703
7704 //===========================================================================
7705 // Returns a location which is (distance) away from (src) in the direction of (targ).
7706 //
7707 function MeleeGetProjectedLoc takes location src, location targ, real distance, real deltaAngle returns location
7708 local real srcX = GetLocationX(src)
7709 local real srcY = GetLocationY(src)
7710 local real direction = Atan2(GetLocationY(targ) - srcY, GetLocationX(targ) - srcX) + deltaAngle
7711 return Location(srcX + distance * Cos(direction), srcY + distance * Sin(direction))
7712 endfunction
7713
7714 //===========================================================================
7715 function MeleeGetNearestValueWithin takes real val, real minVal, real maxVal returns real
7716 if (val < minVal) then
7717 return minVal
7718 elseif (val > maxVal) then
7719 return maxVal
7720 else
7721 return val
7722 endif
7723 endfunction
7724
7725 //===========================================================================
7726 function MeleeGetLocWithinRect takes location src, rect r returns location
7727 local real withinX = MeleeGetNearestValueWithin(GetLocationX(src), GetRectMinX(r), GetRectMaxX(r))
7728 local real withinY = MeleeGetNearestValueWithin(GetLocationY(src), GetRectMinY(r), GetRectMaxY(r))
7729 return Location(withinX, withinY)
7730 endfunction
7731
7732 //===========================================================================
7733 // Starting Units for Human Players
7734 // - 1 Town Hall, placed at start location
7735 // - 5 Peasants, placed between start location and nearest gold mine
7736 //
7737 function MeleeStartingUnitsHuman takes player whichPlayer, location startLoc, boolean doHeroes, boolean doCamera, boolean doPreload returns nothing
7738 local boolean useRandomHero = IsMapFlagSet(MAP_RANDOM_HERO)
7739 local real unitSpacing = 64.00
7740 local unit nearestMine
7741 local location nearMineLoc
7742 local location heroLoc
7743 local real peonX
7744 local real peonY
7745 local unit townHall = null
7746
7747 if (doPreload) then
7748 call Preloader( "scripts\\HumanMelee.pld" )
7749 endif
7750
7751 set nearestMine = MeleeFindNearestMine(startLoc, bj_MELEE_MINE_SEARCH_RADIUS)
7752 if (nearestMine != null) then
7753 // Spawn Town Hall at the start location.
7754 set townHall = CreateUnitAtLoc(whichPlayer, 'htow', startLoc, bj_UNIT_FACING)
7755
7756 // Spawn Peasants near the mine.
7757 set nearMineLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine), startLoc, 320, 0)
7758 set peonX = GetLocationX(nearMineLoc)
7759 set peonY = GetLocationY(nearMineLoc)
7760 call CreateUnit(whichPlayer, 'hpea', peonX + 0.00 * unitSpacing, peonY + 1.00 * unitSpacing, bj_UNIT_FACING)
7761 call CreateUnit(whichPlayer, 'hpea', peonX + 1.00 * unitSpacing, peonY + 0.15 * unitSpacing, bj_UNIT_FACING)
7762 call CreateUnit(whichPlayer, 'hpea', peonX - 1.00 * unitSpacing, peonY + 0.15 * unitSpacing, bj_UNIT_FACING)
7763 call CreateUnit(whichPlayer, 'hpea', peonX + 0.60 * unitSpacing, peonY - 1.00 * unitSpacing, bj_UNIT_FACING)
7764 call CreateUnit(whichPlayer, 'hpea', peonX - 0.60 * unitSpacing, peonY - 1.00 * unitSpacing, bj_UNIT_FACING)
7765
7766 // Set random hero spawn point to be off to the side of the start location.
7767 set heroLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine), startLoc, 384, 45)
7768 else
7769 // Spawn Town Hall at the start location.
7770 set townHall = CreateUnitAtLoc(whichPlayer, 'htow', startLoc, bj_UNIT_FACING)
7771
7772 // Spawn Peasants directly south of the town hall.
7773 set peonX = GetLocationX(startLoc)
7774 set peonY = GetLocationY(startLoc) - 224.00
7775 call CreateUnit(whichPlayer, 'hpea', peonX + 2.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
7776 call CreateUnit(whichPlayer, 'hpea', peonX + 1.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
7777 call CreateUnit(whichPlayer, 'hpea', peonX + 0.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
7778 call CreateUnit(whichPlayer, 'hpea', peonX - 1.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
7779 call CreateUnit(whichPlayer, 'hpea', peonX - 2.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
7780
7781 // Set random hero spawn point to be just south of the start location.
7782 set heroLoc = Location(peonX, peonY - 2.00 * unitSpacing)
7783 endif
7784
7785 if (townHall != null) then
7786 call UnitAddAbilityBJ('Amic', townHall)
7787 call UnitMakeAbilityPermanentBJ(true, 'Amic', townHall)
7788 endif
7789
7790 if (doHeroes) then
7791 // If the "Random Hero" option is set, start the player with a random hero.
7792 // Otherwise, give them a "free hero" token.
7793 if useRandomHero then
7794 call MeleeRandomHeroLoc(whichPlayer, 'Hamg', 'Hmkg', 'Hpal', 'Hblm', heroLoc)
7795 else
7796 call SetPlayerState(whichPlayer, PLAYER_STATE_RESOURCE_HERO_TOKENS, bj_MELEE_STARTING_HERO_TOKENS)
7797 endif
7798 endif
7799
7800 if (doCamera) then
7801 // Center the camera on the initial Peasants.
7802 call SetCameraPositionForPlayer(whichPlayer, peonX, peonY)
7803 call SetCameraQuickPositionForPlayer(whichPlayer, peonX, peonY)
7804 endif
7805 endfunction
7806
7807 //===========================================================================
7808 // Starting Units for Orc Players
7809 // - 1 Great Hall, placed at start location
7810 // - 5 Peons, placed between start location and nearest gold mine
7811 //
7812 function MeleeStartingUnitsOrc takes player whichPlayer, location startLoc, boolean doHeroes, boolean doCamera, boolean doPreload returns nothing
7813 local boolean useRandomHero = IsMapFlagSet(MAP_RANDOM_HERO)
7814 local real unitSpacing = 64.00
7815 local unit nearestMine
7816 local location nearMineLoc
7817 local location heroLoc
7818 local real peonX
7819 local real peonY
7820
7821 if (doPreload) then
7822 call Preloader( "scripts\\OrcMelee.pld" )
7823 endif
7824
7825 set nearestMine = MeleeFindNearestMine(startLoc, bj_MELEE_MINE_SEARCH_RADIUS)
7826 if (nearestMine != null) then
7827 // Spawn Great Hall at the start location.
7828 call CreateUnitAtLoc(whichPlayer, 'ogre', startLoc, bj_UNIT_FACING)
7829
7830 // Spawn Peons near the mine.
7831 set nearMineLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine), startLoc, 320, 0)
7832 set peonX = GetLocationX(nearMineLoc)
7833 set peonY = GetLocationY(nearMineLoc)
7834 call CreateUnit(whichPlayer, 'opeo', peonX + 0.00 * unitSpacing, peonY + 1.00 * unitSpacing, bj_UNIT_FACING)
7835 call CreateUnit(whichPlayer, 'opeo', peonX + 1.00 * unitSpacing, peonY + 0.15 * unitSpacing, bj_UNIT_FACING)
7836 call CreateUnit(whichPlayer, 'opeo', peonX - 1.00 * unitSpacing, peonY + 0.15 * unitSpacing, bj_UNIT_FACING)
7837 call CreateUnit(whichPlayer, 'opeo', peonX + 0.60 * unitSpacing, peonY - 1.00 * unitSpacing, bj_UNIT_FACING)
7838 call CreateUnit(whichPlayer, 'opeo', peonX - 0.60 * unitSpacing, peonY - 1.00 * unitSpacing, bj_UNIT_FACING)
7839
7840 // Set random hero spawn point to be off to the side of the start location.
7841 set heroLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine), startLoc, 384, 45)
7842 else
7843 // Spawn Great Hall at the start location.
7844 call CreateUnitAtLoc(whichPlayer, 'ogre', startLoc, bj_UNIT_FACING)
7845
7846 // Spawn Peons directly south of the town hall.
7847 set peonX = GetLocationX(startLoc)
7848 set peonY = GetLocationY(startLoc) - 224.00
7849 call CreateUnit(whichPlayer, 'opeo', peonX + 2.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
7850 call CreateUnit(whichPlayer, 'opeo', peonX + 1.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
7851 call CreateUnit(whichPlayer, 'opeo', peonX + 0.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
7852 call CreateUnit(whichPlayer, 'opeo', peonX - 1.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
7853 call CreateUnit(whichPlayer, 'opeo', peonX - 2.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
7854
7855 // Set random hero spawn point to be just south of the start location.
7856 set heroLoc = Location(peonX, peonY - 2.00 * unitSpacing)
7857 endif
7858
7859 if (doHeroes) then
7860 // If the "Random Hero" option is set, start the player with a random hero.
7861 // Otherwise, give them a "free hero" token.
7862 if useRandomHero then
7863 call MeleeRandomHeroLoc(whichPlayer, 'Obla', 'Ofar', 'Otch', 'Oshd', heroLoc)
7864 else
7865 call SetPlayerState(whichPlayer, PLAYER_STATE_RESOURCE_HERO_TOKENS, bj_MELEE_STARTING_HERO_TOKENS)
7866 endif
7867 endif
7868
7869 if (doCamera) then
7870 // Center the camera on the initial Peons.
7871 call SetCameraPositionForPlayer(whichPlayer, peonX, peonY)
7872 call SetCameraQuickPositionForPlayer(whichPlayer, peonX, peonY)
7873 endif
7874 endfunction
7875
7876 //===========================================================================
7877 // Starting Units for Undead Players
7878 // - 1 Necropolis, placed at start location
7879 // - 1 Haunted Gold Mine, placed on nearest gold mine
7880 // - 3 Acolytes, placed between start location and nearest gold mine
7881 // - 1 Ghoul, placed between start location and nearest gold mine
7882 // - Blight, centered on nearest gold mine, spread across a "large area"
7883 //
7884 function MeleeStartingUnitsUndead takes player whichPlayer, location startLoc, boolean doHeroes, boolean doCamera, boolean doPreload returns nothing
7885 local boolean useRandomHero = IsMapFlagSet(MAP_RANDOM_HERO)
7886 local real unitSpacing = 64.00
7887 local unit nearestMine
7888 local location nearMineLoc
7889 local location nearTownLoc
7890 local location heroLoc
7891 local real peonX
7892 local real peonY
7893 local real ghoulX
7894 local real ghoulY
7895
7896 if (doPreload) then
7897 call Preloader( "scripts\\UndeadMelee.pld" )
7898 endif
7899
7900 set nearestMine = MeleeFindNearestMine(startLoc, bj_MELEE_MINE_SEARCH_RADIUS)
7901 if (nearestMine != null) then
7902 // Spawn Necropolis at the start location.
7903 call CreateUnitAtLoc(whichPlayer, 'unpl', startLoc, bj_UNIT_FACING)
7904
7905 // Replace the nearest gold mine with a blighted version.
7906 set nearestMine = BlightGoldMineForPlayerBJ(nearestMine, whichPlayer)
7907
7908 // Spawn Ghoul near the Necropolis.
7909 set nearTownLoc = MeleeGetProjectedLoc(startLoc, GetUnitLoc(nearestMine), 288, 0)
7910 set ghoulX = GetLocationX(nearTownLoc)
7911 set ghoulY = GetLocationY(nearTownLoc)
7912 set bj_ghoul[GetPlayerId(whichPlayer)] = CreateUnit(whichPlayer, 'ugho', ghoulX + 0.00 * unitSpacing, ghoulY + 0.00 * unitSpacing, bj_UNIT_FACING)
7913
7914 // Spawn Acolytes near the mine.
7915 set nearMineLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine), startLoc, 320, 0)
7916 set peonX = GetLocationX(nearMineLoc)
7917 set peonY = GetLocationY(nearMineLoc)
7918 call CreateUnit(whichPlayer, 'uaco', peonX + 0.00 * unitSpacing, peonY + 0.50 * unitSpacing, bj_UNIT_FACING)
7919 call CreateUnit(whichPlayer, 'uaco', peonX + 0.65 * unitSpacing, peonY - 0.50 * unitSpacing, bj_UNIT_FACING)
7920 call CreateUnit(whichPlayer, 'uaco', peonX - 0.65 * unitSpacing, peonY - 0.50 * unitSpacing, bj_UNIT_FACING)
7921
7922 // Create a patch of blight around the gold mine.
7923 call SetBlightLoc(whichPlayer,nearMineLoc, 768, true)
7924
7925 // Set random hero spawn point to be off to the side of the start location.
7926 set heroLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine), startLoc, 384, 45)
7927 else
7928 // Spawn Necropolis at the start location.
7929 call CreateUnitAtLoc(whichPlayer, 'unpl', startLoc, bj_UNIT_FACING)
7930
7931 // Spawn Acolytes and Ghoul directly south of the Necropolis.
7932 set peonX = GetLocationX(startLoc)
7933 set peonY = GetLocationY(startLoc) - 224.00
7934 call CreateUnit(whichPlayer, 'uaco', peonX - 1.50 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
7935 call CreateUnit(whichPlayer, 'uaco', peonX - 0.50 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
7936 call CreateUnit(whichPlayer, 'uaco', peonX + 0.50 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
7937 call CreateUnit(whichPlayer, 'ugho', peonX + 1.50 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
7938
7939 // Create a patch of blight around the start location.
7940 call SetBlightLoc(whichPlayer,startLoc, 768, true)
7941
7942 // Set random hero spawn point to be just south of the start location.
7943 set heroLoc = Location(peonX, peonY - 2.00 * unitSpacing)
7944 endif
7945
7946 if (doHeroes) then
7947 // If the "Random Hero" option is set, start the player with a random hero.
7948 // Otherwise, give them a "free hero" token.
7949 if useRandomHero then
7950 call MeleeRandomHeroLoc(whichPlayer, 'Udea', 'Udre', 'Ulic', 'Ucrl', heroLoc)
7951 else
7952 call SetPlayerState(whichPlayer, PLAYER_STATE_RESOURCE_HERO_TOKENS, bj_MELEE_STARTING_HERO_TOKENS)
7953 endif
7954 endif
7955
7956 if (doCamera) then
7957 // Center the camera on the initial Acolytes.
7958 call SetCameraPositionForPlayer(whichPlayer, peonX, peonY)
7959 call SetCameraQuickPositionForPlayer(whichPlayer, peonX, peonY)
7960 endif
7961 endfunction
7962
7963 //===========================================================================
7964 // Starting Units for Night Elf Players
7965 // - 1 Tree of Life, placed by nearest gold mine, already entangled
7966 // - 5 Wisps, placed between Tree of Life and nearest gold mine
7967 //
7968 function MeleeStartingUnitsNightElf takes player whichPlayer, location startLoc, boolean doHeroes, boolean doCamera, boolean doPreload returns nothing
7969 local boolean useRandomHero = IsMapFlagSet(MAP_RANDOM_HERO)
7970 local real unitSpacing = 64.00
7971 local real minTreeDist = 3.50 * bj_CELLWIDTH
7972 local real minWispDist = 1.75 * bj_CELLWIDTH
7973 local unit nearestMine
7974 local location nearMineLoc
7975 local location wispLoc
7976 local location heroLoc
7977 local real peonX
7978 local real peonY
7979 local unit tree
7980
7981 if (doPreload) then
7982 call Preloader( "scripts\\NightElfMelee.pld" )
7983 endif
7984
7985 set nearestMine = MeleeFindNearestMine(startLoc, bj_MELEE_MINE_SEARCH_RADIUS)
7986 if (nearestMine != null) then
7987 // Spawn Tree of Life near the mine and have it entangle the mine.
7988 // Project the Tree's coordinates from the gold mine, and then snap
7989 // the X and Y values to within minTreeDist of the Gold Mine.
7990 set nearMineLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine), startLoc, 650, 0)
7991 set nearMineLoc = MeleeGetLocWithinRect(nearMineLoc, GetRectFromCircleBJ(GetUnitLoc(nearestMine), minTreeDist))
7992 set tree = CreateUnitAtLoc(whichPlayer, 'etol', nearMineLoc, bj_UNIT_FACING)
7993 call IssueTargetOrder(tree, "entangleinstant", nearestMine)
7994
7995 // Spawn Wisps at the start location.
7996 set wispLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine), startLoc, 320, 0)
7997 set wispLoc = MeleeGetLocWithinRect(wispLoc, GetRectFromCircleBJ(GetUnitLoc(nearestMine), minWispDist))
7998 set peonX = GetLocationX(wispLoc)
7999 set peonY = GetLocationY(wispLoc)
8000 call CreateUnit(whichPlayer, 'ewsp', peonX + 0.00 * unitSpacing, peonY + 1.00 * unitSpacing, bj_UNIT_FACING)
8001 call CreateUnit(whichPlayer, 'ewsp', peonX + 1.00 * unitSpacing, peonY + 0.15 * unitSpacing, bj_UNIT_FACING)
8002 call CreateUnit(whichPlayer, 'ewsp', peonX - 1.00 * unitSpacing, peonY + 0.15 * unitSpacing, bj_UNIT_FACING)
8003 call CreateUnit(whichPlayer, 'ewsp', peonX + 0.58 * unitSpacing, peonY - 1.00 * unitSpacing, bj_UNIT_FACING)
8004 call CreateUnit(whichPlayer, 'ewsp', peonX - 0.58 * unitSpacing, peonY - 1.00 * unitSpacing, bj_UNIT_FACING)
8005
8006 // Set random hero spawn point to be off to the side of the start location.
8007 set heroLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine), startLoc, 384, 45)
8008 else
8009 // Spawn Tree of Life at the start location.
8010 call CreateUnitAtLoc(whichPlayer, 'etol', startLoc, bj_UNIT_FACING)
8011
8012 // Spawn Wisps directly south of the town hall.
8013 set peonX = GetLocationX(startLoc)
8014 set peonY = GetLocationY(startLoc) - 224.00
8015 call CreateUnit(whichPlayer, 'ewsp', peonX - 2.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
8016 call CreateUnit(whichPlayer, 'ewsp', peonX - 1.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
8017 call CreateUnit(whichPlayer, 'ewsp', peonX + 0.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
8018 call CreateUnit(whichPlayer, 'ewsp', peonX + 1.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
8019 call CreateUnit(whichPlayer, 'ewsp', peonX + 2.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
8020
8021 // Set random hero spawn point to be just south of the start location.
8022 set heroLoc = Location(peonX, peonY - 2.00 * unitSpacing)
8023 endif
8024
8025 if (doHeroes) then
8026 // If the "Random Hero" option is set, start the player with a random hero.
8027 // Otherwise, give them a "free hero" token.
8028 if useRandomHero then
8029 call MeleeRandomHeroLoc(whichPlayer, 'Edem', 'Ekee', 'Emoo', 'Ewar', heroLoc)
8030 else
8031 call SetPlayerState(whichPlayer, PLAYER_STATE_RESOURCE_HERO_TOKENS, bj_MELEE_STARTING_HERO_TOKENS)
8032 endif
8033 endif
8034
8035 if (doCamera) then
8036 // Center the camera on the initial Wisps.
8037 call SetCameraPositionForPlayer(whichPlayer, peonX, peonY)
8038 call SetCameraQuickPositionForPlayer(whichPlayer, peonX, peonY)
8039 endif
8040 endfunction
8041
8042 //===========================================================================
8043 // Starting Units for Players Whose Race is Unknown
8044 // - 12 Sheep, placed randomly around the start location
8045 //
8046 function MeleeStartingUnitsUnknownRace takes player whichPlayer, location startLoc, boolean doHeroes, boolean doCamera, boolean doPreload returns nothing
8047 local integer index
8048
8049 if (doPreload) then
8050 endif
8051
8052 set index = 0
8053 loop
8054 call CreateUnit(whichPlayer, 'nshe', GetLocationX(startLoc) + GetRandomReal(-256, 256), GetLocationY(startLoc) + GetRandomReal(-256, 256), GetRandomReal(0, 360))
8055 set index = index + 1
8056 exitwhen index == 12
8057 endloop
8058
8059 if (doHeroes) then
8060 // Give them a "free hero" token, out of pity.
8061 call SetPlayerState(whichPlayer, PLAYER_STATE_RESOURCE_HERO_TOKENS, bj_MELEE_STARTING_HERO_TOKENS)
8062 endif
8063
8064 if (doCamera) then
8065 // Center the camera on the initial sheep.
8066 call SetCameraPositionLocForPlayer(whichPlayer, startLoc)
8067 call SetCameraQuickPositionLocForPlayer(whichPlayer, startLoc)
8068 endif
8069 endfunction
8070
8071 //===========================================================================
8072 function MeleeStartingUnits takes nothing returns nothing
8073 local integer index
8074 local player indexPlayer
8075 local location indexStartLoc
8076 local race indexRace
8077
8078 call Preloader( "scripts\\SharedMelee.pld" )
8079
8080 set index = 0
8081 loop
8082 set indexPlayer = Player(index)
8083 if (GetPlayerSlotState(indexPlayer) == PLAYER_SLOT_STATE_PLAYING) then
8084 set indexStartLoc = GetStartLocationLoc(GetPlayerStartLocation(indexPlayer))
8085 set indexRace = GetPlayerRace(indexPlayer)
8086
8087 // Create initial race-specific starting units
8088 if (indexRace == RACE_HUMAN) then
8089 call MeleeStartingUnitsHuman(indexPlayer, indexStartLoc, true, true, true)
8090 elseif (indexRace == RACE_ORC) then
8091 call MeleeStartingUnitsOrc(indexPlayer, indexStartLoc, true, true, true)
8092 elseif (indexRace == RACE_UNDEAD) then
8093 call MeleeStartingUnitsUndead(indexPlayer, indexStartLoc, true, true, true)
8094 elseif (indexRace == RACE_NIGHTELF) then
8095 call MeleeStartingUnitsNightElf(indexPlayer, indexStartLoc, true, true, true)
8096 else
8097 call MeleeStartingUnitsUnknownRace(indexPlayer, indexStartLoc, true, true, true)
8098 endif
8099 endif
8100
8101 set index = index + 1
8102 exitwhen index == bj_MAX_PLAYERS
8103 endloop
8104
8105 endfunction
8106
8107 //===========================================================================
8108 function MeleeStartingUnitsForPlayer takes race whichRace, player whichPlayer, location loc, boolean doHeroes returns nothing
8109 // Create initial race-specific starting units
8110 if (whichRace == RACE_HUMAN) then
8111 call MeleeStartingUnitsHuman(whichPlayer, loc, doHeroes, false, false)
8112 elseif (whichRace == RACE_ORC) then
8113 call MeleeStartingUnitsOrc(whichPlayer, loc, doHeroes, false, false)
8114 elseif (whichRace == RACE_UNDEAD) then
8115 call MeleeStartingUnitsUndead(whichPlayer, loc, doHeroes, false, false)
8116 elseif (whichRace == RACE_NIGHTELF) then
8117 call MeleeStartingUnitsNightElf(whichPlayer, loc, doHeroes, false, false)
8118 else
8119 // Unrecognized race - ignore the request.
8120 endif
8121 endfunction
8122
8123
8124
8125 //***************************************************************************
8126 //*
8127 //* Melee Template Starting AI Scripts
8128 //*
8129 //***************************************************************************
8130
8131 //===========================================================================
8132 function PickMeleeAI takes player num, string s1, string s2, string s3 returns nothing
8133 local integer pick
8134
8135 // easy difficulty never uses any custom AI scripts
8136 // that are designed to be a bit more challenging
8137 //
8138 if GetAIDifficulty(num) == AI_DIFFICULTY_NEWBIE then
8139 call StartMeleeAI(num,s1)
8140 return
8141 endif
8142
8143 if s2 == null then
8144 set pick = 1
8145 elseif s3 == null then
8146 set pick = GetRandomInt(1,2)
8147 else
8148 set pick = GetRandomInt(1,3)
8149 endif
8150
8151 if pick == 1 then
8152 call StartMeleeAI(num,s1)
8153 elseif pick == 2 then
8154 call StartMeleeAI(num,s2)
8155 else
8156 call StartMeleeAI(num,s3)
8157 endif
8158 endfunction
8159
8160 //===========================================================================
8161 function MeleeStartingAI takes nothing returns nothing
8162 local integer index
8163 local player indexPlayer
8164 local race indexRace
8165
8166 set index = 0
8167 loop
8168 set indexPlayer = Player(index)
8169 if (GetPlayerSlotState(indexPlayer) == PLAYER_SLOT_STATE_PLAYING) then
8170 set indexRace = GetPlayerRace(indexPlayer)
8171 if (GetPlayerController(indexPlayer) == MAP_CONTROL_COMPUTER) then
8172 // Run a race-specific melee AI script.
8173 if (indexRace == RACE_HUMAN) then
8174 call PickMeleeAI(indexPlayer, "human.ai", null, null)
8175 elseif (indexRace == RACE_ORC) then
8176 call PickMeleeAI(indexPlayer, "orc.ai", null, null)
8177 elseif (indexRace == RACE_UNDEAD) then
8178 call PickMeleeAI(indexPlayer, "undead.ai", null, null)
8179 call RecycleGuardPosition(bj_ghoul[index])
8180 elseif (indexRace == RACE_NIGHTELF) then
8181 call PickMeleeAI(indexPlayer, "elf.ai", null, null)
8182 else
8183 // Unrecognized race.
8184 endif
8185 call ShareEverythingWithTeamAI(indexPlayer)
8186 endif
8187 endif
8188
8189 set index = index + 1
8190 exitwhen index == bj_MAX_PLAYERS
8191 endloop
8192 endfunction
8193
8194 function LockGuardPosition takes unit targ returns nothing
8195 call SetUnitCreepGuard(targ,true)
8196 endfunction
8197
8198
8199 //***************************************************************************
8200 //*
8201 //* Melee Template Victory / Defeat Conditions
8202 //*
8203 //***************************************************************************
8204
8205 //===========================================================================
8206 function MeleePlayerIsOpponent takes integer playerIndex, integer opponentIndex returns boolean
8207 local player thePlayer = Player(playerIndex)
8208 local player theOpponent = Player(opponentIndex)
8209
8210 // The player himself is not an opponent.
8211 if (playerIndex == opponentIndex) then
8212 return false
8213 endif
8214
8215 // Unused player slots are not opponents.
8216 if (GetPlayerSlotState(theOpponent) != PLAYER_SLOT_STATE_PLAYING) then
8217 return false
8218 endif
8219
8220 // Players who are already defeated are not opponents.
8221 if (bj_meleeDefeated[opponentIndex]) then
8222 return false
8223 endif
8224
8225 // Allied players with allied victory set are not opponents.
8226 if GetPlayerAlliance(thePlayer, theOpponent, ALLIANCE_PASSIVE) then
8227 if GetPlayerAlliance(theOpponent, thePlayer, ALLIANCE_PASSIVE) then
8228 if (GetPlayerState(thePlayer, PLAYER_STATE_ALLIED_VICTORY) == 1) then
8229 if (GetPlayerState(theOpponent, PLAYER_STATE_ALLIED_VICTORY) == 1) then
8230 return false
8231 endif
8232 endif
8233 endif
8234 endif
8235
8236 return true
8237 endfunction
8238
8239 //===========================================================================
8240 // Count buildings currently owned by all allies, including the player themself.
8241 //
8242 function MeleeGetAllyStructureCount takes player whichPlayer returns integer
8243 local integer playerIndex
8244 local integer buildingCount
8245 local player indexPlayer
8246
8247 // Count the number of buildings controlled by all not-yet-defeated co-allies.
8248 set buildingCount = 0
8249 set playerIndex = 0
8250 loop
8251 set indexPlayer = Player(playerIndex)
8252
8253 // uncomment to cause defeat even if you have control of ally structures, but yours have been nixed
8254 //if (PlayersAreCoAllied(whichPlayer, indexPlayer) and not bj_meleeDefeated[playerIndex]) then
8255 if (PlayersAreCoAllied(whichPlayer, indexPlayer)) then
8256 set buildingCount = buildingCount + GetPlayerStructureCount(indexPlayer, true)
8257 endif
8258
8259 set playerIndex = playerIndex + 1
8260 exitwhen playerIndex == bj_MAX_PLAYERS
8261 endloop
8262
8263 return buildingCount
8264 endfunction
8265
8266 //===========================================================================
8267 // Count allies, excluding dead players and the player themself.
8268 //
8269 function MeleeGetAllyCount takes player whichPlayer returns integer
8270 local integer playerIndex
8271 local integer playerCount
8272 local player indexPlayer
8273
8274 // Count the number of not-yet-defeated co-allies.
8275 set playerCount = 0
8276 set playerIndex = 0
8277 loop
8278 set indexPlayer = Player(playerIndex)
8279 if PlayersAreCoAllied(whichPlayer, indexPlayer) and not bj_meleeDefeated[playerIndex] and (whichPlayer != indexPlayer) then
8280 set playerCount = playerCount + 1
8281 endif
8282
8283 set playerIndex = playerIndex + 1
8284 exitwhen playerIndex == bj_MAX_PLAYERS
8285 endloop
8286
8287 return playerCount
8288 endfunction
8289
8290 //===========================================================================
8291 // Counts key structures owned by a player and his or her allies, including
8292 // structures currently upgrading or under construction.
8293 //
8294 // Key structures: Town Hall, Great Hall, Tree of Life, Necropolis
8295 //
8296 function MeleeGetAllyKeyStructureCount takes player whichPlayer returns integer
8297 local integer playerIndex
8298 local player indexPlayer
8299 local integer keyStructs
8300
8301 // Count the number of buildings controlled by all not-yet-defeated co-allies.
8302 set keyStructs = 0
8303 set playerIndex = 0
8304 loop
8305 set indexPlayer = Player(playerIndex)
8306 if (PlayersAreCoAllied(whichPlayer, indexPlayer)) then
8307 set keyStructs = keyStructs + GetPlayerTypedUnitCount(indexPlayer, "townhall", true, true)
8308 set keyStructs = keyStructs + GetPlayerTypedUnitCount(indexPlayer, "greathall", true, true)
8309 set keyStructs = keyStructs + GetPlayerTypedUnitCount(indexPlayer, "treeoflife", true, true)
8310 set keyStructs = keyStructs + GetPlayerTypedUnitCount(indexPlayer, "necropolis", true, true)
8311 endif
8312
8313 set playerIndex = playerIndex + 1
8314 exitwhen playerIndex == bj_MAX_PLAYERS
8315 endloop
8316
8317 return keyStructs
8318 endfunction
8319
8320 //===========================================================================
8321 // Enum: Draw out a specific player.
8322 //
8323 function MeleeDoDrawEnum takes nothing returns nothing
8324 local player thePlayer = GetEnumPlayer()
8325
8326 call CachePlayerHeroData(thePlayer)
8327 call RemovePlayerPreserveUnitsBJ(thePlayer, PLAYER_GAME_RESULT_TIE, false)
8328 endfunction
8329
8330 //===========================================================================
8331 // Enum: Victory out a specific player.
8332 //
8333 function MeleeDoVictoryEnum takes nothing returns nothing
8334 local player thePlayer = GetEnumPlayer()
8335 local integer playerIndex = GetPlayerId(thePlayer)
8336
8337 if (not bj_meleeVictoried[playerIndex]) then
8338 set bj_meleeVictoried[playerIndex] = true
8339 call CachePlayerHeroData(thePlayer)
8340 call RemovePlayerPreserveUnitsBJ(thePlayer, PLAYER_GAME_RESULT_VICTORY, false)
8341 endif
8342 endfunction
8343
8344 //===========================================================================
8345 // Defeat out a specific player.
8346 //
8347 function MeleeDoDefeat takes player whichPlayer returns nothing
8348 set bj_meleeDefeated[GetPlayerId(whichPlayer)] = true
8349 call RemovePlayerPreserveUnitsBJ(whichPlayer, PLAYER_GAME_RESULT_DEFEAT, false)
8350 endfunction
8351
8352 //===========================================================================
8353 // Enum: Defeat out a specific player.
8354 //
8355 function MeleeDoDefeatEnum takes nothing returns nothing
8356 local player thePlayer = GetEnumPlayer()
8357
8358 // needs to happen before ownership change
8359 call CachePlayerHeroData(thePlayer)
8360 call MakeUnitsPassiveForTeam(thePlayer)
8361 call MeleeDoDefeat(thePlayer)
8362 endfunction
8363
8364 //===========================================================================
8365 // A specific player left the game.
8366 //
8367 function MeleeDoLeave takes player whichPlayer returns nothing
8368 if (GetIntegerGameState(GAME_STATE_DISCONNECTED) != 0) then
8369 call GameOverDialogBJ( whichPlayer, true )
8370 else
8371 set bj_meleeDefeated[GetPlayerId(whichPlayer)] = true
8372 call RemovePlayerPreserveUnitsBJ(whichPlayer, PLAYER_GAME_RESULT_DEFEAT, true)
8373 endif
8374 endfunction
8375
8376 //===========================================================================
8377 // Remove all observers
8378 //
8379 function MeleeRemoveObservers takes nothing returns nothing
8380 local integer playerIndex
8381 local player indexPlayer
8382
8383 // Give all observers the game over dialog
8384 set playerIndex = 0
8385 loop
8386 set indexPlayer = Player(playerIndex)
8387
8388 if (IsPlayerObserver(indexPlayer)) then
8389 call RemovePlayerPreserveUnitsBJ(indexPlayer, PLAYER_GAME_RESULT_NEUTRAL, false)
8390 endif
8391
8392 set playerIndex = playerIndex + 1
8393 exitwhen playerIndex == bj_MAX_PLAYERS
8394 endloop
8395 endfunction
8396
8397 //===========================================================================
8398 // Test all players to determine if a team has won. For a team to win, all
8399 // remaining (read: undefeated) players need to be co-allied with all other
8400 // remaining players. If even one player is not allied towards another,
8401 // everyone must be denied victory.
8402 //
8403 function MeleeCheckForVictors takes nothing returns force
8404 local integer playerIndex
8405 local integer opponentIndex
8406 local force opponentlessPlayers = CreateForce()
8407 local boolean gameOver = false
8408
8409 // Check to see if any players have opponents remaining.
8410 set playerIndex = 0
8411 loop
8412 if (not bj_meleeDefeated[playerIndex]) then
8413 // Determine whether or not this player has any remaining opponents.
8414 set opponentIndex = 0
8415 loop
8416 // If anyone has an opponent, noone can be victorious yet.
8417 if MeleePlayerIsOpponent(playerIndex, opponentIndex) then
8418 return CreateForce()
8419 endif
8420
8421 set opponentIndex = opponentIndex + 1
8422 exitwhen opponentIndex == bj_MAX_PLAYERS
8423 endloop
8424
8425 // Keep track of each opponentless player so that we can give
8426 // them a victory later.
8427 call ForceAddPlayer(opponentlessPlayers, Player(playerIndex))
8428 set gameOver = true
8429 endif
8430
8431 set playerIndex = playerIndex + 1
8432 exitwhen playerIndex == bj_MAX_PLAYERS
8433 endloop
8434
8435 // Set the game over global flag
8436 set bj_meleeGameOver = gameOver
8437
8438 return opponentlessPlayers
8439 endfunction
8440
8441 //===========================================================================
8442 // Test each player to determine if anyone has been defeated.
8443 //
8444 function MeleeCheckForLosersAndVictors takes nothing returns nothing
8445 local integer playerIndex
8446 local player indexPlayer
8447 local force defeatedPlayers = CreateForce()
8448 local force victoriousPlayers
8449 local boolean gameOver = false
8450
8451 // If the game is already over, do nothing
8452 if (bj_meleeGameOver) then
8453 return
8454 endif
8455
8456 // If the game was disconnected then it is over, in this case we
8457 // don't want to report results for anyone as they will most likely
8458 // conflict with the actual game results
8459 if (GetIntegerGameState(GAME_STATE_DISCONNECTED) != 0) then
8460 set bj_meleeGameOver = true
8461 return
8462 endif
8463
8464 // Check each player to see if he or she has been defeated yet.
8465 set playerIndex = 0
8466 loop
8467 set indexPlayer = Player(playerIndex)
8468
8469 if (not bj_meleeDefeated[playerIndex] and not bj_meleeVictoried[playerIndex]) then
8470 //call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "Player"+I2S(playerIndex)+" has "+I2S(MeleeGetAllyStructureCount(indexPlayer))+" ally buildings.")
8471 if (MeleeGetAllyStructureCount(indexPlayer) <= 0) then
8472
8473 // Keep track of each defeated player so that we can give
8474 // them a defeat later.
8475 call ForceAddPlayer(defeatedPlayers, Player(playerIndex))
8476
8477 // Set their defeated flag now so MeleeCheckForVictors
8478 // can detect victors.
8479 set bj_meleeDefeated[playerIndex] = true
8480 endif
8481 endif
8482
8483 set playerIndex = playerIndex + 1
8484 exitwhen playerIndex == bj_MAX_PLAYERS
8485 endloop
8486
8487 // Now that the defeated flags are set, check if there are any victors
8488 set victoriousPlayers = MeleeCheckForVictors()
8489
8490 // Defeat all defeated players
8491 call ForForce(defeatedPlayers, function MeleeDoDefeatEnum)
8492
8493 // Give victory to all victorious players
8494 call ForForce(victoriousPlayers, function MeleeDoVictoryEnum)
8495
8496 // If the game is over we should remove all observers
8497 if (bj_meleeGameOver) then
8498 call MeleeRemoveObservers()
8499 endif
8500 endfunction
8501
8502 //===========================================================================
8503 // Returns a race-specific "build X or be revealed" message.
8504 //
8505 function MeleeGetCrippledWarningMessage takes player whichPlayer returns string
8506 local race r = GetPlayerRace(whichPlayer)
8507
8508 if (r == RACE_HUMAN) then
8509 return GetLocalizedString("CRIPPLE_WARNING_HUMAN")
8510 elseif (r == RACE_ORC) then
8511 return GetLocalizedString("CRIPPLE_WARNING_ORC")
8512 elseif (r == RACE_NIGHTELF) then
8513 return GetLocalizedString("CRIPPLE_WARNING_NIGHTELF")
8514 elseif (r == RACE_UNDEAD) then
8515 return GetLocalizedString("CRIPPLE_WARNING_UNDEAD")
8516 else
8517 // Unrecognized Race
8518 return ""
8519 endif
8520 endfunction
8521
8522 //===========================================================================
8523 // Returns a race-specific "build X" label for cripple timers.
8524 //
8525 function MeleeGetCrippledTimerMessage takes player whichPlayer returns string
8526 local race r = GetPlayerRace(whichPlayer)
8527
8528 if (r == RACE_HUMAN) then
8529 return GetLocalizedString("CRIPPLE_TIMER_HUMAN")
8530 elseif (r == RACE_ORC) then
8531 return GetLocalizedString("CRIPPLE_TIMER_ORC")
8532 elseif (r == RACE_NIGHTELF) then
8533 return GetLocalizedString("CRIPPLE_TIMER_NIGHTELF")
8534 elseif (r == RACE_UNDEAD) then
8535 return GetLocalizedString("CRIPPLE_TIMER_UNDEAD")
8536 else
8537 // Unrecognized Race
8538 return ""
8539 endif
8540 endfunction
8541
8542 //===========================================================================
8543 // Returns a race-specific "build X" label for cripple timers.
8544 //
8545 function MeleeGetCrippledRevealedMessage takes player whichPlayer returns string
8546 return GetLocalizedString("CRIPPLE_REVEALING_PREFIX") + GetPlayerName(whichPlayer) + GetLocalizedString("CRIPPLE_REVEALING_POSTFIX")
8547 endfunction
8548
8549 //===========================================================================
8550 function MeleeExposePlayer takes player whichPlayer, boolean expose returns nothing
8551 local integer playerIndex
8552 local player indexPlayer
8553 local force toExposeTo = CreateForce()
8554
8555 call CripplePlayer( whichPlayer, toExposeTo, false )
8556
8557 set bj_playerIsExposed[GetPlayerId(whichPlayer)] = expose
8558 set playerIndex = 0
8559 loop
8560 set indexPlayer = Player(playerIndex)
8561 if (not PlayersAreCoAllied(whichPlayer, indexPlayer)) then
8562 call ForceAddPlayer( toExposeTo, indexPlayer )
8563 endif
8564
8565 set playerIndex = playerIndex + 1
8566 exitwhen playerIndex == bj_MAX_PLAYERS
8567 endloop
8568
8569 call CripplePlayer( whichPlayer, toExposeTo, expose )
8570 call DestroyForce(toExposeTo)
8571 endfunction
8572
8573 //===========================================================================
8574 function MeleeExposeAllPlayers takes nothing returns nothing
8575 local integer playerIndex
8576 local player indexPlayer
8577 local integer playerIndex2
8578 local player indexPlayer2
8579 local force toExposeTo = CreateForce()
8580
8581 set playerIndex = 0
8582 loop
8583 set indexPlayer = Player(playerIndex)
8584
8585 call ForceClear( toExposeTo )
8586 call CripplePlayer( indexPlayer, toExposeTo, false )
8587
8588 set playerIndex2 = 0
8589 loop
8590 set indexPlayer2 = Player(playerIndex2)
8591
8592 if playerIndex != playerIndex2 then
8593 if (not PlayersAreCoAllied(indexPlayer, indexPlayer2)) then
8594 call ForceAddPlayer( toExposeTo, indexPlayer2 )
8595 endif
8596 endif
8597
8598 set playerIndex2 = playerIndex2 + 1
8599 exitwhen playerIndex2 == bj_MAX_PLAYERS
8600 endloop
8601
8602 call CripplePlayer( indexPlayer, toExposeTo, true )
8603
8604 set playerIndex = playerIndex + 1
8605 exitwhen playerIndex == bj_MAX_PLAYERS
8606 endloop
8607
8608 call DestroyForce( toExposeTo )
8609 endfunction
8610
8611 //===========================================================================
8612 function MeleeCrippledPlayerTimeout takes nothing returns nothing
8613 local timer expiredTimer = GetExpiredTimer()
8614 local integer playerIndex
8615 local player exposedPlayer
8616
8617 // Determine which player's timer expired.
8618 set playerIndex = 0
8619 loop
8620 if (bj_crippledTimer[playerIndex] == expiredTimer) then
8621 exitwhen true
8622 endif
8623
8624 set playerIndex = playerIndex + 1
8625 exitwhen playerIndex == bj_MAX_PLAYERS
8626 endloop
8627 if (playerIndex == bj_MAX_PLAYERS) then
8628 return
8629 endif
8630 set exposedPlayer = Player(playerIndex)
8631
8632 if (GetLocalPlayer() == exposedPlayer) then
8633 // Use only local code (no net traffic) within this block to avoid desyncs.
8634
8635 // Hide the timer window for this player.
8636 call TimerDialogDisplay(bj_crippledTimerWindows[playerIndex], false)
8637 endif
8638
8639 // Display a text message to all players, explaining the exposure.
8640 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_MELEE_CRIPPLE_MSG_DURATION, MeleeGetCrippledRevealedMessage(exposedPlayer))
8641
8642 // Expose the player.
8643 call MeleeExposePlayer(exposedPlayer, true)
8644 endfunction
8645
8646 //===========================================================================
8647 function MeleePlayerIsCrippled takes player whichPlayer returns boolean
8648 local integer allyStructures = MeleeGetAllyStructureCount(whichPlayer)
8649 local integer allyKeyStructures = MeleeGetAllyKeyStructureCount(whichPlayer)
8650
8651 // Dead teams are not considered to be crippled.
8652 return (allyStructures > 0) and (allyKeyStructures <= 0)
8653 endfunction
8654
8655 //===========================================================================
8656 // Test each player to determine if anyone has become crippled.
8657 //
8658 function MeleeCheckForCrippledPlayers takes nothing returns nothing
8659 local integer playerIndex
8660 local player indexPlayer
8661 local force crippledPlayers = CreateForce()
8662 local boolean isNowCrippled
8663 local race indexRace
8664
8665 // The "finish soon" exposure of all players overrides any "crippled" exposure
8666 if bj_finishSoonAllExposed then
8667 return
8668 endif
8669
8670 // Check each player to see if he or she has been crippled or uncrippled.
8671 set playerIndex = 0
8672 loop
8673 set indexPlayer = Player(playerIndex)
8674 set isNowCrippled = MeleePlayerIsCrippled(indexPlayer)
8675
8676 if (not bj_playerIsCrippled[playerIndex] and isNowCrippled) then
8677
8678 // Player became crippled; start their cripple timer.
8679 set bj_playerIsCrippled[playerIndex] = true
8680 call TimerStart(bj_crippledTimer[playerIndex], bj_MELEE_CRIPPLE_TIMEOUT, false, function MeleeCrippledPlayerTimeout)
8681
8682 if (GetLocalPlayer() == indexPlayer) then
8683 // Use only local code (no net traffic) within this block to avoid desyncs.
8684
8685 // Show the timer window.
8686 call TimerDialogDisplay(bj_crippledTimerWindows[playerIndex], true)
8687
8688 // Display a warning message.
8689 call DisplayTimedTextToPlayer(indexPlayer, 0, 0, bj_MELEE_CRIPPLE_MSG_DURATION, MeleeGetCrippledWarningMessage(indexPlayer))
8690 endif
8691
8692 elseif (bj_playerIsCrippled[playerIndex] and not isNowCrippled) then
8693
8694 // Player became uncrippled; stop their cripple timer.
8695 set bj_playerIsCrippled[playerIndex] = false
8696 call PauseTimer(bj_crippledTimer[playerIndex])
8697
8698 if (GetLocalPlayer() == indexPlayer) then
8699 // Use only local code (no net traffic) within this block to avoid desyncs.
8700
8701 // Hide the timer window for this player.
8702 call TimerDialogDisplay(bj_crippledTimerWindows[playerIndex], false)
8703
8704 // Display a confirmation message if the player's team is still alive.
8705 if (MeleeGetAllyStructureCount(indexPlayer) > 0) then
8706 if (bj_playerIsExposed[playerIndex]) then
8707 call DisplayTimedTextToPlayer(indexPlayer, 0, 0, bj_MELEE_CRIPPLE_MSG_DURATION, GetLocalizedString("CRIPPLE_UNREVEALED"))
8708 else
8709 call DisplayTimedTextToPlayer(indexPlayer, 0, 0, bj_MELEE_CRIPPLE_MSG_DURATION, GetLocalizedString("CRIPPLE_UNCRIPPLED"))
8710 endif
8711 endif
8712 endif
8713
8714 // If the player granted shared vision, deny that vision now.
8715 call MeleeExposePlayer(indexPlayer, false)
8716
8717 endif
8718
8719 set playerIndex = playerIndex + 1
8720 exitwhen playerIndex == bj_MAX_PLAYERS
8721 endloop
8722 endfunction
8723
8724 //===========================================================================
8725 // Determine if the lost unit should result in any defeats or victories.
8726 //
8727 function MeleeCheckLostUnit takes unit lostUnit returns nothing
8728 local player lostUnitOwner = GetOwningPlayer(lostUnit)
8729
8730 // We only need to check for mortality if this was the last building.
8731 if (GetPlayerStructureCount(lostUnitOwner, true) <= 0) then
8732 call MeleeCheckForLosersAndVictors()
8733 endif
8734
8735 // Check if the lost unit has crippled or uncrippled the player.
8736 // (A team with 0 units is dead, and thus considered uncrippled.)
8737 call MeleeCheckForCrippledPlayers()
8738 endfunction
8739
8740 //===========================================================================
8741 // Determine if the gained unit should result in any defeats, victories,
8742 // or cripple-status changes.
8743 //
8744 function MeleeCheckAddedUnit takes unit addedUnit returns nothing
8745 local player addedUnitOwner = GetOwningPlayer(addedUnit)
8746
8747 // If the player was crippled, this unit may have uncrippled him/her.
8748 if (bj_playerIsCrippled[GetPlayerId(addedUnitOwner)]) then
8749 call MeleeCheckForCrippledPlayers()
8750 endif
8751 endfunction
8752
8753 //===========================================================================
8754 function MeleeTriggerActionConstructCancel takes nothing returns nothing
8755 call MeleeCheckLostUnit(GetCancelledStructure())
8756 endfunction
8757
8758 //===========================================================================
8759 function MeleeTriggerActionUnitDeath takes nothing returns nothing
8760 if (IsUnitType(GetDyingUnit(), UNIT_TYPE_STRUCTURE)) then
8761 call MeleeCheckLostUnit(GetDyingUnit())
8762 endif
8763 endfunction
8764
8765 //===========================================================================
8766 function MeleeTriggerActionUnitConstructionStart takes nothing returns nothing
8767 call MeleeCheckAddedUnit(GetConstructingStructure())
8768 endfunction
8769
8770 //===========================================================================
8771 function MeleeTriggerActionPlayerDefeated takes nothing returns nothing
8772 local player thePlayer = GetTriggerPlayer()
8773 call CachePlayerHeroData(thePlayer)
8774
8775 if (MeleeGetAllyCount(thePlayer) > 0) then
8776 // If at least one ally is still alive and kicking, share units with
8777 // them and proceed with death.
8778 call ShareEverythingWithTeam(thePlayer)
8779 if (not bj_meleeDefeated[GetPlayerId(thePlayer)]) then
8780 call MeleeDoDefeat(thePlayer)
8781 endif
8782 else
8783 // If no living allies remain, swap all units and buildings over to
8784 // neutral_passive and proceed with death.
8785 call MakeUnitsPassiveForTeam(thePlayer)
8786 if (not bj_meleeDefeated[GetPlayerId(thePlayer)]) then
8787 call MeleeDoDefeat(thePlayer)
8788 endif
8789 endif
8790 call MeleeCheckForLosersAndVictors()
8791 endfunction
8792
8793 //===========================================================================
8794 function MeleeTriggerActionPlayerLeft takes nothing returns nothing
8795 local player thePlayer = GetTriggerPlayer()
8796
8797 // Just show game over for observers when they leave
8798 if (IsPlayerObserver(thePlayer)) then
8799 call RemovePlayerPreserveUnitsBJ(thePlayer, PLAYER_GAME_RESULT_NEUTRAL, false)
8800 return
8801 endif
8802
8803 call CachePlayerHeroData(thePlayer)
8804
8805 // This is the same as defeat except the player generates the message
8806 // "player left the game" as opposed to "player was defeated".
8807
8808 if (MeleeGetAllyCount(thePlayer) > 0) then
8809 // If at least one ally is still alive and kicking, share units with
8810 // them and proceed with death.
8811 call ShareEverythingWithTeam(thePlayer)
8812 call MeleeDoLeave(thePlayer)
8813 else
8814 // If no living allies remain, swap all units and buildings over to
8815 // neutral_passive and proceed with death.
8816 call MakeUnitsPassiveForTeam(thePlayer)
8817 call MeleeDoLeave(thePlayer)
8818 endif
8819 call MeleeCheckForLosersAndVictors()
8820 endfunction
8821
8822 //===========================================================================
8823 function MeleeTriggerActionAllianceChange takes nothing returns nothing
8824 call MeleeCheckForLosersAndVictors()
8825 call MeleeCheckForCrippledPlayers()
8826 endfunction
8827
8828 //===========================================================================
8829 function MeleeTriggerTournamentFinishSoon takes nothing returns nothing
8830 // Note: We may get this trigger multiple times
8831 local integer playerIndex
8832 local player indexPlayer
8833 local real timeRemaining = GetTournamentFinishSoonTimeRemaining()
8834
8835 if not bj_finishSoonAllExposed then
8836 set bj_finishSoonAllExposed = true
8837
8838 // Reset all crippled players and their timers, and hide the local crippled timer dialog
8839 set playerIndex = 0
8840 loop
8841 set indexPlayer = Player(playerIndex)
8842 if bj_playerIsCrippled[playerIndex] then
8843 // Uncripple the player
8844 set bj_playerIsCrippled[playerIndex] = false
8845 call PauseTimer(bj_crippledTimer[playerIndex])
8846
8847 if (GetLocalPlayer() == indexPlayer) then
8848 // Use only local code (no net traffic) within this block to avoid desyncs.
8849
8850 // Hide the timer window.
8851 call TimerDialogDisplay(bj_crippledTimerWindows[playerIndex], false)
8852 endif
8853
8854 endif
8855 set playerIndex = playerIndex + 1
8856 exitwhen playerIndex == bj_MAX_PLAYERS
8857 endloop
8858
8859 // Expose all players
8860 call MeleeExposeAllPlayers()
8861 endif
8862
8863 // Show the "finish soon" timer dialog and set the real time remaining
8864 call TimerDialogDisplay(bj_finishSoonTimerDialog, true)
8865 call TimerDialogSetRealTimeRemaining(bj_finishSoonTimerDialog, timeRemaining)
8866 endfunction
8867
8868
8869 //===========================================================================
8870 function MeleeWasUserPlayer takes player whichPlayer returns boolean
8871 local playerslotstate slotState
8872
8873 if (GetPlayerController(whichPlayer) != MAP_CONTROL_USER) then
8874 return false
8875 endif
8876
8877 set slotState = GetPlayerSlotState(whichPlayer)
8878
8879 return (slotState == PLAYER_SLOT_STATE_PLAYING or slotState == PLAYER_SLOT_STATE_LEFT)
8880 endfunction
8881
8882 //===========================================================================
8883 function MeleeTournamentFinishNowRuleA takes integer multiplier returns nothing
8884 local integer array playerScore
8885 local integer array teamScore
8886 local force array teamForce
8887 local integer teamCount
8888 local integer index
8889 local player indexPlayer
8890 local integer index2
8891 local player indexPlayer2
8892 local integer bestTeam
8893 local integer bestScore
8894 local boolean draw
8895
8896 // Compute individual player scores
8897 set index = 0
8898 loop
8899 set indexPlayer = Player(index)
8900 if MeleeWasUserPlayer(indexPlayer) then
8901 set playerScore[index] = GetTournamentScore(indexPlayer)
8902 if playerScore[index] <= 0 then
8903 set playerScore[index] = 1
8904 endif
8905 else
8906 set playerScore[index] = 0
8907 endif
8908 set index = index + 1
8909 exitwhen index == bj_MAX_PLAYERS
8910 endloop
8911
8912 // Compute team scores and team forces
8913 set teamCount = 0
8914 set index = 0
8915 loop
8916 if playerScore[index] != 0 then
8917 set indexPlayer = Player(index)
8918
8919 set teamScore[teamCount] = 0
8920 set teamForce[teamCount] = CreateForce()
8921
8922 set index2 = index
8923 loop
8924 if playerScore[index2] != 0 then
8925 set indexPlayer2 = Player(index2)
8926
8927 if PlayersAreCoAllied(indexPlayer, indexPlayer2) then
8928 set teamScore[teamCount] = teamScore[teamCount] + playerScore[index2]
8929 call ForceAddPlayer(teamForce[teamCount], indexPlayer2)
8930 set playerScore[index2] = 0
8931 endif
8932 endif
8933
8934 set index2 = index2 + 1
8935 exitwhen index2 == bj_MAX_PLAYERS
8936 endloop
8937
8938 set teamCount = teamCount + 1
8939 endif
8940
8941 set index = index + 1
8942 exitwhen index == bj_MAX_PLAYERS
8943 endloop
8944
8945 // The game is now over
8946 set bj_meleeGameOver = true
8947
8948 // There should always be at least one team, but continue to work if not
8949 if teamCount != 0 then
8950
8951 // Find best team score
8952 set bestTeam = -1
8953 set bestScore = -1
8954 set index = 0
8955 loop
8956 if teamScore[index] > bestScore then
8957 set bestTeam = index
8958 set bestScore = teamScore[index]
8959 endif
8960
8961 set index = index + 1
8962 exitwhen index == teamCount
8963 endloop
8964
8965 // Check whether the best team's score is 'multiplier' times better than
8966 // every other team. In the case of multiplier == 1 and exactly equal team
8967 // scores, the first team (which was randomly chosen by the server) will win.
8968 set draw = false
8969 set index = 0
8970 loop
8971 if index != bestTeam then
8972 if bestScore < (multiplier * teamScore[index]) then
8973 set draw = true
8974 endif
8975 endif
8976
8977 set index = index + 1
8978 exitwhen index == teamCount
8979 endloop
8980
8981 if draw then
8982 // Give draw to all players on all teams
8983 set index = 0
8984 loop
8985 call ForForce(teamForce[index], function MeleeDoDrawEnum)
8986
8987 set index = index + 1
8988 exitwhen index == teamCount
8989 endloop
8990 else
8991 // Give defeat to all players on teams other than the best team
8992 set index = 0
8993 loop
8994 if index != bestTeam then
8995 call ForForce(teamForce[index], function MeleeDoDefeatEnum)
8996 endif
8997
8998 set index = index + 1
8999 exitwhen index == teamCount
9000 endloop
9001
9002 // Give victory to all players on the best team
9003 call ForForce(teamForce[bestTeam], function MeleeDoVictoryEnum)
9004 endif
9005 endif
9006
9007 endfunction
9008
9009 //===========================================================================
9010 function MeleeTriggerTournamentFinishNow takes nothing returns nothing
9011 local integer rule = GetTournamentFinishNowRule()
9012
9013 // If the game is already over, do nothing
9014 if bj_meleeGameOver then
9015 return
9016 endif
9017
9018 if (rule == 1) then
9019 // Finals games
9020 call MeleeTournamentFinishNowRuleA(1)
9021 else
9022 // Preliminary games
9023 call MeleeTournamentFinishNowRuleA(3)
9024 endif
9025
9026 // Since the game is over we should remove all observers
9027 call MeleeRemoveObservers()
9028
9029 endfunction
9030
9031 //===========================================================================
9032 function MeleeInitVictoryDefeat takes nothing returns nothing
9033 local trigger trig
9034 local integer index
9035 local player indexPlayer
9036
9037 // Create a timer window for the "finish soon" timeout period, it has no timer
9038 // because it is driven by real time (outside of the game state to avoid desyncs)
9039 set bj_finishSoonTimerDialog = CreateTimerDialog(null)
9040
9041 // Set a trigger to fire when we receive a "finish soon" game event
9042 set trig = CreateTrigger()
9043 call TriggerRegisterGameEvent(trig, EVENT_GAME_TOURNAMENT_FINISH_SOON)
9044 call TriggerAddAction(trig, function MeleeTriggerTournamentFinishSoon)
9045
9046 // Set a trigger to fire when we receive a "finish now" game event
9047 set trig = CreateTrigger()
9048 call TriggerRegisterGameEvent(trig, EVENT_GAME_TOURNAMENT_FINISH_NOW)
9049 call TriggerAddAction(trig, function MeleeTriggerTournamentFinishNow)
9050
9051 // Set up each player's mortality code.
9052 set index = 0
9053 loop
9054 set indexPlayer = Player(index)
9055
9056 // Make sure this player slot is playing.
9057 if (GetPlayerSlotState(indexPlayer) == PLAYER_SLOT_STATE_PLAYING) then
9058 set bj_meleeDefeated[index] = false
9059 set bj_meleeVictoried[index] = false
9060
9061 // Create a timer and timer window in case the player is crippled.
9062 set bj_playerIsCrippled[index] = false
9063 set bj_playerIsExposed[index] = false
9064 set bj_crippledTimer[index] = CreateTimer()
9065 set bj_crippledTimerWindows[index] = CreateTimerDialog(bj_crippledTimer[index])
9066 call TimerDialogSetTitle(bj_crippledTimerWindows[index], MeleeGetCrippledTimerMessage(indexPlayer))
9067
9068 // Set a trigger to fire whenever a building is cancelled for this player.
9069 set trig = CreateTrigger()
9070 call TriggerRegisterPlayerUnitEvent(trig, indexPlayer, EVENT_PLAYER_UNIT_CONSTRUCT_CANCEL, null)
9071 call TriggerAddAction(trig, function MeleeTriggerActionConstructCancel)
9072
9073 // Set a trigger to fire whenever a unit dies for this player.
9074 set trig = CreateTrigger()
9075 call TriggerRegisterPlayerUnitEvent(trig, indexPlayer, EVENT_PLAYER_UNIT_DEATH, null)
9076 call TriggerAddAction(trig, function MeleeTriggerActionUnitDeath)
9077
9078 // Set a trigger to fire whenever a unit begins construction for this player
9079 set trig = CreateTrigger()
9080 call TriggerRegisterPlayerUnitEvent(trig, indexPlayer, EVENT_PLAYER_UNIT_CONSTRUCT_START, null)
9081 call TriggerAddAction(trig, function MeleeTriggerActionUnitConstructionStart)
9082
9083 // Set a trigger to fire whenever this player defeats-out
9084 set trig = CreateTrigger()
9085 call TriggerRegisterPlayerEvent(trig, indexPlayer, EVENT_PLAYER_DEFEAT)
9086 call TriggerAddAction(trig, function MeleeTriggerActionPlayerDefeated)
9087
9088 // Set a trigger to fire whenever this player leaves
9089 set trig = CreateTrigger()
9090 call TriggerRegisterPlayerEvent(trig, indexPlayer, EVENT_PLAYER_LEAVE)
9091 call TriggerAddAction(trig, function MeleeTriggerActionPlayerLeft)
9092
9093 // Set a trigger to fire whenever this player changes his/her alliances.
9094 set trig = CreateTrigger()
9095 call TriggerRegisterPlayerAllianceChange(trig, indexPlayer, ALLIANCE_PASSIVE)
9096 call TriggerRegisterPlayerStateEvent(trig, indexPlayer, PLAYER_STATE_ALLIED_VICTORY, EQUAL, 1)
9097 call TriggerAddAction(trig, function MeleeTriggerActionAllianceChange)
9098 else
9099 set bj_meleeDefeated[index] = true
9100 set bj_meleeVictoried[index] = false
9101
9102 // Handle leave events for observers
9103 if (IsPlayerObserver(indexPlayer)) then
9104 // Set a trigger to fire whenever this player leaves
9105 set trig = CreateTrigger()
9106 call TriggerRegisterPlayerEvent(trig, indexPlayer, EVENT_PLAYER_LEAVE)
9107 call TriggerAddAction(trig, function MeleeTriggerActionPlayerLeft)
9108 endif
9109 endif
9110
9111 set index = index + 1
9112 exitwhen index == bj_MAX_PLAYERS
9113 endloop
9114
9115 // Test for victory / defeat at startup, in case the user has already won / lost.
9116 // Allow for a short time to pass first, so that the map can finish loading.
9117 call TimerStart(CreateTimer(), 2.0, false, function MeleeTriggerActionAllianceChange)
9118 endfunction
9119
9120
9121
9122 //***************************************************************************
9123 //*
9124 //* Player Slot Availability
9125 //*
9126 //***************************************************************************
9127
9128 //===========================================================================
9129 function CheckInitPlayerSlotAvailability takes nothing returns nothing
9130 local integer index
9131
9132 if (not bj_slotControlReady) then
9133 set index = 0
9134 loop
9135 set bj_slotControlUsed[index] = false
9136 set bj_slotControl[index] = MAP_CONTROL_USER
9137 set index = index + 1
9138 exitwhen index == bj_MAX_PLAYERS
9139 endloop
9140 set bj_slotControlReady = true
9141 endif
9142 endfunction
9143
9144 //===========================================================================
9145 function SetPlayerSlotAvailable takes player whichPlayer, mapcontrol control returns nothing
9146 local integer playerIndex = GetPlayerId(whichPlayer)
9147
9148 call CheckInitPlayerSlotAvailability()
9149 set bj_slotControlUsed[playerIndex] = true
9150 set bj_slotControl[playerIndex] = control
9151 endfunction
9152
9153
9154
9155 //***************************************************************************
9156 //*
9157 //* Generic Template Player-slot Initialization
9158 //*
9159 //***************************************************************************
9160
9161 //===========================================================================
9162 function TeamInitPlayerSlots takes integer teamCount returns nothing
9163 local integer index
9164 local player indexPlayer
9165 local integer team
9166
9167 call SetTeams(teamCount)
9168
9169 call CheckInitPlayerSlotAvailability()
9170 set index = 0
9171 set team = 0
9172 loop
9173 if (bj_slotControlUsed[index]) then
9174 set indexPlayer = Player(index)
9175 call SetPlayerTeam( indexPlayer, team )
9176 set team = team + 1
9177 if (team >= teamCount) then
9178 set team = 0
9179 endif
9180 endif
9181
9182 set index = index + 1
9183 exitwhen index == bj_MAX_PLAYERS
9184 endloop
9185 endfunction
9186
9187 //===========================================================================
9188 function MeleeInitPlayerSlots takes nothing returns nothing
9189 call TeamInitPlayerSlots(bj_MAX_PLAYERS)
9190 endfunction
9191
9192 //===========================================================================
9193 function FFAInitPlayerSlots takes nothing returns nothing
9194 call TeamInitPlayerSlots(bj_MAX_PLAYERS)
9195 endfunction
9196
9197 //===========================================================================
9198 function OneOnOneInitPlayerSlots takes nothing returns nothing
9199 // Limit the game to 2 players.
9200 call SetTeams(2)
9201 call SetPlayers(2)
9202 call TeamInitPlayerSlots(2)
9203 endfunction
9204
9205 //===========================================================================
9206 function InitGenericPlayerSlots takes nothing returns nothing
9207 local gametype gType = GetGameTypeSelected()
9208
9209 if (gType == GAME_TYPE_MELEE) then
9210 call MeleeInitPlayerSlots()
9211 elseif (gType == GAME_TYPE_FFA) then
9212 call FFAInitPlayerSlots()
9213 elseif (gType == GAME_TYPE_USE_MAP_SETTINGS) then
9214 // Do nothing; the map-specific script handles this.
9215 elseif (gType == GAME_TYPE_ONE_ON_ONE) then
9216 call OneOnOneInitPlayerSlots()
9217 elseif (gType == GAME_TYPE_TWO_TEAM_PLAY) then
9218 call TeamInitPlayerSlots(2)
9219 elseif (gType == GAME_TYPE_THREE_TEAM_PLAY) then
9220 call TeamInitPlayerSlots(3)
9221 elseif (gType == GAME_TYPE_FOUR_TEAM_PLAY) then
9222 call TeamInitPlayerSlots(4)
9223 else
9224 // Unrecognized Game Type
9225 endif
9226 endfunction
9227
9228
9229
9230 //***************************************************************************
9231 //*
9232 //* Blizzard.j Initialization
9233 //*
9234 //***************************************************************************
9235
9236 //===========================================================================
9237 function SetDNCSoundsDawn takes nothing returns nothing
9238 if bj_useDawnDuskSounds then
9239 call StartSound(bj_dawnSound)
9240 endif
9241 endfunction
9242
9243 //===========================================================================
9244 function SetDNCSoundsDusk takes nothing returns nothing
9245 if bj_useDawnDuskSounds then
9246 call StartSound(bj_duskSound)
9247 endif
9248 endfunction
9249
9250 //===========================================================================
9251 function SetDNCSoundsDay takes nothing returns nothing
9252 local real ToD = GetTimeOfDay()
9253
9254 if (ToD >= bj_TOD_DAWN and ToD < bj_TOD_DUSK) and not bj_dncIsDaytime then
9255 set bj_dncIsDaytime = true
9256
9257 // change ambient sounds
9258 call StopSound(bj_nightAmbientSound, false, true)
9259 call StartSound(bj_dayAmbientSound)
9260 endif
9261 endfunction
9262
9263 //===========================================================================
9264 function SetDNCSoundsNight takes nothing returns nothing
9265 local real ToD = GetTimeOfDay()
9266
9267 if (ToD < bj_TOD_DAWN or ToD >= bj_TOD_DUSK) and bj_dncIsDaytime then
9268 set bj_dncIsDaytime = false
9269
9270 // change ambient sounds
9271 call StopSound(bj_dayAmbientSound, false, true)
9272 call StartSound(bj_nightAmbientSound)
9273 endif
9274 endfunction
9275
9276 //===========================================================================
9277 function InitDNCSounds takes nothing returns nothing
9278 // Create sounds to be played at dawn and dusk.
9279 set bj_dawnSound = CreateSoundFromLabel("RoosterSound", false, false, false, 10000, 10000)
9280 set bj_duskSound = CreateSoundFromLabel("WolfSound", false, false, false, 10000, 10000)
9281
9282 // Set up triggers to respond to dawn and dusk.
9283 set bj_dncSoundsDawn = CreateTrigger()
9284 call TriggerRegisterGameStateEvent(bj_dncSoundsDawn, GAME_STATE_TIME_OF_DAY, EQUAL, bj_TOD_DAWN)
9285 call TriggerAddAction(bj_dncSoundsDawn, function SetDNCSoundsDawn)
9286
9287 set bj_dncSoundsDusk = CreateTrigger()
9288 call TriggerRegisterGameStateEvent(bj_dncSoundsDusk, GAME_STATE_TIME_OF_DAY, EQUAL, bj_TOD_DUSK)
9289 call TriggerAddAction(bj_dncSoundsDusk, function SetDNCSoundsDusk)
9290
9291 // Set up triggers to respond to changes from day to night or vice-versa.
9292 set bj_dncSoundsDay = CreateTrigger()
9293 call TriggerRegisterGameStateEvent(bj_dncSoundsDay, GAME_STATE_TIME_OF_DAY, GREATER_THAN_OR_EQUAL, bj_TOD_DAWN)
9294 call TriggerRegisterGameStateEvent(bj_dncSoundsDay, GAME_STATE_TIME_OF_DAY, LESS_THAN, bj_TOD_DUSK)
9295 call TriggerAddAction(bj_dncSoundsDay, function SetDNCSoundsDay)
9296
9297 set bj_dncSoundsNight = CreateTrigger()
9298 call TriggerRegisterGameStateEvent(bj_dncSoundsNight, GAME_STATE_TIME_OF_DAY, LESS_THAN, bj_TOD_DAWN)
9299 call TriggerRegisterGameStateEvent(bj_dncSoundsNight, GAME_STATE_TIME_OF_DAY, GREATER_THAN_OR_EQUAL, bj_TOD_DUSK)
9300 call TriggerAddAction(bj_dncSoundsNight, function SetDNCSoundsNight)
9301 endfunction
9302
9303 //===========================================================================
9304 function InitBlizzardGlobals takes nothing returns nothing
9305 local integer index
9306 local integer userControlledPlayers
9307 local version v
9308
9309 // Init filter function vars
9310 set filterIssueHauntOrderAtLocBJ = Filter(function IssueHauntOrderAtLocBJFilter)
9311 set filterEnumDestructablesInCircleBJ = Filter(function EnumDestructablesInCircleBJFilter)
9312 set filterGetUnitsInRectOfPlayer = Filter(function GetUnitsInRectOfPlayerFilter)
9313 set filterGetUnitsOfTypeIdAll = Filter(function GetUnitsOfTypeIdAllFilter)
9314 set filterGetUnitsOfPlayerAndTypeId = Filter(function GetUnitsOfPlayerAndTypeIdFilter)
9315 set filterMeleeTrainedUnitIsHeroBJ = Filter(function MeleeTrainedUnitIsHeroBJFilter)
9316 set filterLivingPlayerUnitsOfTypeId = Filter(function LivingPlayerUnitsOfTypeIdFilter)
9317
9318 // Init force presets
9319 set index = 0
9320 loop
9321 exitwhen index == bj_MAX_PLAYER_SLOTS
9322 set bj_FORCE_PLAYER[index] = CreateForce()
9323 call ForceAddPlayer(bj_FORCE_PLAYER[index], Player(index))
9324 set index = index + 1
9325 endloop
9326
9327 set bj_FORCE_ALL_PLAYERS = CreateForce()
9328 call ForceEnumPlayers(bj_FORCE_ALL_PLAYERS, null)
9329
9330 // Init Cinematic Mode history
9331 set bj_cineModePriorSpeed = GetGameSpeed()
9332 set bj_cineModePriorFogSetting = IsFogEnabled()
9333 set bj_cineModePriorMaskSetting = IsFogMaskEnabled()
9334
9335 // Init Trigger Queue
9336 set index = 0
9337 loop
9338 exitwhen index >= bj_MAX_QUEUED_TRIGGERS
9339 set bj_queuedExecTriggers[index] = null
9340 set bj_queuedExecUseConds[index] = false
9341 set index = index + 1
9342 endloop
9343
9344 // Init singleplayer check
9345 set bj_isSinglePlayer = false
9346 set userControlledPlayers = 0
9347 set index = 0
9348 loop
9349 exitwhen index >= bj_MAX_PLAYERS
9350 if (GetPlayerController(Player(index)) == MAP_CONTROL_USER and GetPlayerSlotState(Player(index)) == PLAYER_SLOT_STATE_PLAYING) then
9351 set userControlledPlayers = userControlledPlayers + 1
9352 endif
9353 set index = index + 1
9354 endloop
9355 set bj_isSinglePlayer = (userControlledPlayers == 1)
9356
9357 // Init sounds
9358 //set bj_pingMinimapSound = CreateSoundFromLabel("AutoCastButtonClick", false, false, false, 10000, 10000)
9359 set bj_rescueSound = CreateSoundFromLabel("Rescue", false, false, false, 10000, 10000)
9360 set bj_questDiscoveredSound = CreateSoundFromLabel("QuestNew", false, false, false, 10000, 10000)
9361 set bj_questUpdatedSound = CreateSoundFromLabel("QuestUpdate", false, false, false, 10000, 10000)
9362 set bj_questCompletedSound = CreateSoundFromLabel("QuestCompleted", false, false, false, 10000, 10000)
9363 set bj_questFailedSound = CreateSoundFromLabel("QuestFailed", false, false, false, 10000, 10000)
9364 set bj_questHintSound = CreateSoundFromLabel("Hint", false, false, false, 10000, 10000)
9365 set bj_questSecretSound = CreateSoundFromLabel("SecretFound", false, false, false, 10000, 10000)
9366 set bj_questItemAcquiredSound = CreateSoundFromLabel("ItemReward", false, false, false, 10000, 10000)
9367 set bj_questWarningSound = CreateSoundFromLabel("Warning", false, false, false, 10000, 10000)
9368 set bj_victoryDialogSound = CreateSoundFromLabel("QuestCompleted", false, false, false, 10000, 10000)
9369 set bj_defeatDialogSound = CreateSoundFromLabel("QuestFailed", false, false, false, 10000, 10000)
9370
9371 // Init corpse creation triggers.
9372 call DelayedSuspendDecayCreate()
9373
9374 // Init version-specific data
9375 set v = VersionGet()
9376 if (v == VERSION_REIGN_OF_CHAOS) then
9377 set bj_MELEE_MAX_TWINKED_HEROES = bj_MELEE_MAX_TWINKED_HEROES_V0
9378 else
9379 set bj_MELEE_MAX_TWINKED_HEROES = bj_MELEE_MAX_TWINKED_HEROES_V1
9380 endif
9381 endfunction
9382
9383 //===========================================================================
9384 function InitQueuedTriggers takes nothing returns nothing
9385 set bj_queuedExecTimeout = CreateTrigger()
9386 call TriggerRegisterTimerExpireEvent(bj_queuedExecTimeout, bj_queuedExecTimeoutTimer)
9387 call TriggerAddAction(bj_queuedExecTimeout, function QueuedTriggerDoneBJ)
9388 endfunction
9389
9390 //===========================================================================
9391 function InitMapRects takes nothing returns nothing
9392 set bj_mapInitialPlayableArea = Rect(GetCameraBoundMinX()-GetCameraMargin(CAMERA_MARGIN_LEFT), GetCameraBoundMinY()-GetCameraMargin(CAMERA_MARGIN_BOTTOM), GetCameraBoundMaxX()+GetCameraMargin(CAMERA_MARGIN_RIGHT), GetCameraBoundMaxY()+GetCameraMargin(CAMERA_MARGIN_TOP))
9393 set bj_mapInitialCameraBounds = GetCurrentCameraBoundsMapRectBJ()
9394 endfunction
9395
9396 //===========================================================================
9397 function InitSummonableCaps takes nothing returns nothing
9398 local integer index
9399
9400 set index = 0
9401 loop
9402 // upgraded units
9403 // Note: Only do this if the corresponding upgrade is not yet researched
9404 // Barrage - Siege Engines
9405 if (not GetPlayerTechResearched(Player(index), 'Rhrt', true)) then
9406 call SetPlayerTechMaxAllowed(Player(index), 'hrtt', 0)
9407 endif
9408
9409 // Berserker Upgrade - Troll Berserkers
9410 if (not GetPlayerTechResearched(Player(index), 'Robk', true)) then
9411 call SetPlayerTechMaxAllowed(Player(index), 'otbk', 0)
9412 endif
9413
9414 // max skeletons per player
9415 call SetPlayerTechMaxAllowed(Player(index), 'uske', bj_MAX_SKELETONS)
9416
9417 set index = index + 1
9418 exitwhen index == bj_MAX_PLAYERS
9419 endloop
9420 endfunction
9421
9422 //===========================================================================
9423 // Update the per-class stock limits.
9424 //
9425 function UpdateStockAvailability takes item whichItem returns nothing
9426 local itemtype iType = GetItemType(whichItem)
9427 local integer iLevel = GetItemLevel(whichItem)
9428
9429 // Update allowed type/level combinations.
9430 if (iType == ITEM_TYPE_PERMANENT) then
9431 set bj_stockAllowedPermanent[iLevel] = true
9432 elseif (iType == ITEM_TYPE_CHARGED) then
9433 set bj_stockAllowedCharged[iLevel] = true
9434 elseif (iType == ITEM_TYPE_ARTIFACT) then
9435 set bj_stockAllowedArtifact[iLevel] = true
9436 else
9437 // Not interested in this item type - ignore the item.
9438 endif
9439 endfunction
9440
9441 //===========================================================================
9442 // Find a sellable item of the given type and level, and then add it.
9443 //
9444 function UpdateEachStockBuildingEnum takes nothing returns nothing
9445 local integer iteration = 0
9446 local integer pickedItemId
9447
9448 loop
9449 set pickedItemId = ChooseRandomItemEx(bj_stockPickedItemType, bj_stockPickedItemLevel)
9450 exitwhen IsItemIdSellable(pickedItemId)
9451
9452 // If we get hung up on an entire class/level combo of unsellable
9453 // items, or a very unlucky series of random numbers, give up.
9454 set iteration = iteration + 1
9455 if (iteration > bj_STOCK_MAX_ITERATIONS) then
9456 return
9457 endif
9458 endloop
9459 call AddItemToStock(GetEnumUnit(), pickedItemId, 1, 1)
9460 endfunction
9461
9462 //===========================================================================
9463 function UpdateEachStockBuilding takes itemtype iType, integer iLevel returns nothing
9464 local group g
9465
9466 set bj_stockPickedItemType = iType
9467 set bj_stockPickedItemLevel = iLevel
9468
9469 set g = CreateGroup()
9470 call GroupEnumUnitsOfType(g, "marketplace", null)
9471 call ForGroup(g, function UpdateEachStockBuildingEnum)
9472 call DestroyGroup(g)
9473 endfunction
9474
9475 //===========================================================================
9476 // Update stock inventory.
9477 //
9478 function PerformStockUpdates takes nothing returns nothing
9479 local integer pickedItemId
9480 local itemtype pickedItemType
9481 local integer pickedItemLevel = 0
9482 local integer allowedCombinations = 0
9483 local integer iLevel
9484
9485 // Give each type/level combination a chance of being picked.
9486 set iLevel = 1
9487 loop
9488 if (bj_stockAllowedPermanent[iLevel]) then
9489 set allowedCombinations = allowedCombinations + 1
9490 if (GetRandomInt(1, allowedCombinations) == 1) then
9491 set pickedItemType = ITEM_TYPE_PERMANENT
9492 set pickedItemLevel = iLevel
9493 endif
9494 endif
9495 if (bj_stockAllowedCharged[iLevel]) then
9496 set allowedCombinations = allowedCombinations + 1
9497 if (GetRandomInt(1, allowedCombinations) == 1) then
9498 set pickedItemType = ITEM_TYPE_CHARGED
9499 set pickedItemLevel = iLevel
9500 endif
9501 endif
9502 if (bj_stockAllowedArtifact[iLevel]) then
9503 set allowedCombinations = allowedCombinations + 1
9504 if (GetRandomInt(1, allowedCombinations) == 1) then
9505 set pickedItemType = ITEM_TYPE_ARTIFACT
9506 set pickedItemLevel = iLevel
9507 endif
9508 endif
9509
9510 set iLevel = iLevel + 1
9511 exitwhen iLevel > bj_MAX_ITEM_LEVEL
9512 endloop
9513
9514 // Make sure we found a valid item type to add.
9515 if (allowedCombinations == 0) then
9516 return
9517 endif
9518
9519 call UpdateEachStockBuilding(pickedItemType, pickedItemLevel)
9520 endfunction
9521
9522 /// Perform the first update, and then arrange future updates.
9523 /// @author Blizzard Entertainment
9524 function StartStockUpdates takes nothing returns nothing
9525 call PerformStockUpdates()
9526 call TimerStart(bj_stockUpdateTimer, bj_STOCK_RESTOCK_INTERVAL, true, function PerformStockUpdates)
9527 endfunction
9528
9529 //===========================================================================
9530 function RemovePurchasedItem takes nothing returns nothing
9531 call RemoveItemFromStock(GetSellingUnit(), GetItemTypeId(GetSoldItem()))
9532 endfunction
9533
9534 //===========================================================================
9535 function InitNeutralBuildings takes nothing returns nothing
9536 local integer iLevel
9537
9538 // Chart of allowed stock items.
9539 set iLevel = 0
9540 loop
9541 set bj_stockAllowedPermanent[iLevel] = false
9542 set bj_stockAllowedCharged[iLevel] = false
9543 set bj_stockAllowedArtifact[iLevel] = false
9544 set iLevel = iLevel + 1
9545 exitwhen iLevel > bj_MAX_ITEM_LEVEL
9546 endloop
9547
9548 // Limit stock inventory slots.
9549 call SetAllItemTypeSlots(bj_MAX_STOCK_ITEM_SLOTS)
9550 call SetAllUnitTypeSlots(bj_MAX_STOCK_UNIT_SLOTS)
9551
9552 // Arrange the first update.
9553 set bj_stockUpdateTimer = CreateTimer()
9554 call TimerStart(bj_stockUpdateTimer, bj_STOCK_RESTOCK_INITIAL_DELAY, false, function StartStockUpdates)
9555
9556 // Set up a trigger to fire whenever an item is sold.
9557 set bj_stockItemPurchased = CreateTrigger()
9558 call TriggerRegisterPlayerUnitEvent(bj_stockItemPurchased, Player(PLAYER_NEUTRAL_PASSIVE), EVENT_PLAYER_UNIT_SELL_ITEM, null)
9559 call TriggerAddAction(bj_stockItemPurchased, function RemovePurchasedItem)
9560 endfunction
9561
9562 //===========================================================================
9563 function MarkGameStarted takes nothing returns nothing
9564 set bj_gameStarted = true
9565 call DestroyTimer(bj_gameStartedTimer)
9566 endfunction
9567
9568 //===========================================================================
9569 function DetectGameStarted takes nothing returns nothing
9570 set bj_gameStartedTimer = CreateTimer()
9571 call TimerStart(bj_gameStartedTimer, bj_GAME_STARTED_THRESHOLD, false, function MarkGameStarted)
9572 endfunction
9573
9574 //===========================================================================
9575 function InitBlizzard takes nothing returns nothing
9576 // Set up the Neutral Victim player slot, to torture the abandoned units
9577 // of defeated players. Since some triggers expect this player slot to
9578 // exist, this is performed for all maps.
9579 call ConfigureNeutralVictim()
9580
9581 call InitBlizzardGlobals()
9582 call InitQueuedTriggers()
9583 call InitRescuableBehaviorBJ()
9584 call InitDNCSounds()
9585 call InitMapRects()
9586 call InitSummonableCaps()
9587 call InitNeutralBuildings()
9588 call DetectGameStarted()
9589 endfunction
9590
9591
9592
9593 //***************************************************************************
9594 //*
9595 //* Random distribution
9596 //*
9597 //* Used to select a random object from a given distribution of chances
9598 //*
9599 //* - RandomDistReset clears the distribution list
9600 //*
9601 //* - RandomDistAddItem adds a new object to the distribution list
9602 //* with a given identifier and an integer chance to be chosen
9603 //*
9604 //* - RandomDistChoose will use the current distribution list to choose
9605 //* one of the objects randomly based on the chance distribution
9606 //*
9607 //* Note that the chances are effectively normalized by their sum,
9608 //* so only the relative values of each chance are important
9609 //*
9610 //***************************************************************************
9611
9612 //===========================================================================
9613 function RandomDistReset takes nothing returns nothing
9614 set bj_randDistCount = 0
9615 endfunction
9616
9617 //===========================================================================
9618 function RandomDistAddItem takes integer inID, integer inChance returns nothing
9619 set bj_randDistID[bj_randDistCount] = inID
9620 set bj_randDistChance[bj_randDistCount] = inChance
9621 set bj_randDistCount = bj_randDistCount + 1
9622 endfunction
9623
9624 //===========================================================================
9625 function RandomDistChoose takes nothing returns integer
9626 local integer sum = 0
9627 local integer chance = 0
9628 local integer index
9629 local integer foundID = -1
9630 local boolean done
9631
9632 // No items?
9633 if (bj_randDistCount == 0) then
9634 return -1
9635 endif
9636
9637 // Find sum of all chances
9638 set index = 0
9639 loop
9640 set sum = sum + bj_randDistChance[index]
9641
9642 set index = index + 1
9643 exitwhen index == bj_randDistCount
9644 endloop
9645
9646 // Choose random number within the total range
9647 set chance = GetRandomInt(1, sum)
9648
9649 // Find ID which corresponds to this chance
9650 set index = 0
9651 set sum = 0
9652 set done = false
9653 loop
9654 set sum = sum + bj_randDistChance[index]
9655
9656 if (chance <= sum) then
9657 set foundID = bj_randDistID[index]
9658 set done = true
9659 endif
9660
9661 set index = index + 1
9662 if (index == bj_randDistCount) then
9663 set done = true
9664 endif
9665
9666 exitwhen done == true
9667 endloop
9668
9669 return foundID
9670 endfunction
9671
9672 /// Drop item
9673 /// Makes the given unit drop the given item
9674 /// Note: This could potentially cause problems if the unit is standing
9675 /// right on the edge of an unpathable area and happens to drop the
9676 /// item into the unpathable area where nobody can get it...
9677 /// @author Blizzard Entertainment
9678 function UnitDropItem takes unit inUnit, integer inItemID returns item
9679 local real x
9680 local real y
9681 local real radius = 32
9682 local real unitX
9683 local real unitY
9684 local item droppedItem
9685
9686 if (inItemID == -1) then
9687 return null
9688 endif
9689
9690 set unitX = GetUnitX(inUnit)
9691 set unitY = GetUnitY(inUnit)
9692
9693 set x = GetRandomReal(unitX - radius, unitX + radius)
9694 set y = GetRandomReal(unitY - radius, unitY + radius)
9695
9696 set droppedItem = CreateItem(inItemID, x, y)
9697
9698 call SetItemDropID(droppedItem, GetUnitTypeId(inUnit))
9699 call UpdateStockAvailability(droppedItem)
9700
9701 return droppedItem
9702 endfunction
9703
9704 //===========================================================================
9705 function WidgetDropItem takes widget inWidget, integer inItemID returns item
9706 local real x
9707 local real y
9708 local real radius = 32
9709 local real widgetX
9710 local real widgetY
9711
9712 if (inItemID == -1) then
9713 return null
9714 endif
9715
9716 set widgetX = GetWidgetX(inWidget)
9717 set widgetY = GetWidgetY(inWidget)
9718
9719 set x = GetRandomReal(widgetX - radius, widgetX + radius)
9720 set y = GetRandomReal(widgetY - radius, widgetY + radius)
9721
9722 return CreateItem(inItemID, x, y)
9723 endfunction